Resizing

Every Freighter carousel needs to have some strategy for resizing itself when the width of its parent changes. Freighter includes 4, each with their own set of behaviors.

Resizing the carousel containers on this screen is great for understanding the documentation, but resizing the window can be a hassle. For your convenience, each carousel container has been given some top and bottom padding and a horizontal resize handle. You can use these to resize the container to your liking without needing to change the size of the browser.

What is Resizing?

In order to make Freighter carousels responsive, some strategy needs to be employed to resize the carousel when the width of the container's parent changes. Resizing is just your carousel's reaction to this change. Based on how you are planning on using the carousel, some of the resizing methods may be more appropriate than others.


Resizing Methods

There are 4 different resizing methods to choose from in Freighter. Each of these methods interacts slightly differently with other carousel properties.

The resizing method for a Freighter carousel is indicated in the constructor, as the second parameter. See the code block below that demonstrates how to utilize the resizing method stretch-gap in the carousel myCarousel:

const myCarousel = new Freighter(
  'myCarousel',     // Specify the container ID here.
  'stretch-gap',    // Specify the desired resizing method here.
  'none',           // Specify the desired wrapping method here.
  {},               // Dymamic properties can be specified here.
);
One important thing to note is that the resizing is one of 3 carousel properties not specified within the CarouselProperties object passed to the constructor. This is because the CarouselProperties object only contains the properties that can be changed after the carousel is initialized. Resizing is a fixed property that must be specified at initialization, and therefore does not belong inside of this object.

none

The first and simplest of the resizing methods is none. As you might expect, a carousel with this resizing method will not change its size when the browser window's width changes. The size of the carousel is thus determined by the carousel items within it, as described by the content-first philosophy.

Below is the code necessary to create a carousel with a resizing method of none as well as the resulting carousel. Try resizing the width of the browser window to see how the carousel maintains its size. This code presupposes that <div id="myCarousel"> already exists in the DOM, and has 9 carousel items as children.

const myCarousel = new Freighter(
  'myCarousel',
  'none',
  'none',
  {
    numItemsVisible: 5,
    itemWidth: 50,
    itemHeight: 50,
    itemSpacing: 5,
    scrollBy: 2,
  },
);

Resizing the window will not affect the size of the carousel. In fact, knowing the item height, item width, and item spacing values is enough to calculate the size of the carousel. This is exactly how Freighter performs this calculation under the hood.

For the purposes of this site, the carousel container was given an additional style of overflow: hidden in order to prevent strange behavior when resizing the window. This was applied using a class that was added to the container itself.

As an additional note, the train carousel on the homepage of the site uses a resizing method of none, and opts to manually change the number of items visible when hitting certain breakpoints. Resizing with the none method allows you to customize the resizing behavior manually for another level of customization if none of the offered resizing methods fit your use cases.


stretch

This is the most basic of a number of stretch-like resizing methods. The basic stretch resizing method simply stretches each carousel item to fill the entire width of the carousel container. This is means that the itemWidth is ignored, and only the width of the container, the itemSpacing, and numItemsVisible are used to calculate the width of each item.

Take the code below as an example. Again, this code presupposes that <div id="myCarousel"> already exists in the DOM, and has 9 carousel items as children.

const myCarousel = new Freighter(
  'myCarousel',
  'stretch',
  'none',
  {
    numItemsVisible: 3,
    scrollBy: 3,
    itemHeight: 150,
    itemSpacing: 10,
  },
);

You can see that no matter how wide the carousel's parent container is (dictated partially by the browser width), the only dimension that changes for each carousel item is its width. The itemHeight and itemSpacing remains the same.

The next few resizing methods will all appear to behave in a similar manner to stretch, with minor differences for each variation.


stretch-gap

In this resizing method, it is the itemSpacing that is stretched fill the entire width of the carousel container. The itemSpacing value will not be decreased below its original value, even if the carousel container is smaller than the sum of all the carousel items. In this case, the carousel item overflow will be hidden, so it is up to you to ensure that your parent container does not shrink below an appropriate level.

Below is the code for one of these carousels, as well as the resulting carousel. Again, this code presupposes that <div id="myCarousel"> already exists in the DOM, and has 9 carousel items as children.

const myCarousel = new Freighter(
  'myCarousel',
  'stretch-gap',
  'none',
  {
    numItemsVisible: 3,
    scrollBy: 3,
    itemHeight: 150,
    itemWidth: 175,
    itemSpacing: 10,
  },
);

Because overflowing carousel items will be hidden, this is an effective way of creating carousels that show a small amount of the next elements. Try shrinking your browser window until the left and right elements are cut off by the edges of the carousel parent container. Again, you would need to restrict the minimum and maximum width of this container.


stretch-scale

This variation of the stretch-like resizing methods ensures that the aspect ratio of each carousel item is preserved. The aspect ratio uses the initial values of itemHeight and itemWidth. This is the only resizing method that actually alters the height of a carousel; all of the other methods only adjust the carousel width. The value of itemSpacing, however, remains unchanged.

Below is the code for one of these carousels, as well as the resulting carousel. Again, this code presupposes that <div id="myCarousel"> already exists in the DOM, and has 9 carousel items as children.

const myCarousel = new Freighter(
  'myCarousel',
  'stretch-scale',
  'none',
  {
    numItemsVisible: 3,
    scrollBy: 3,
    itemHeight: 2,
    itemWidth: 3,
    itemSpacing: 10,
  },
);

Note that the itemHeight and itemWidth provided in the original CarouselProperties object are not the actual height and width of the carousel items. Instead, they represent the aspect ratio of the carousel items. Why does this work? Well, the height and width are initially set to these values. However, Freighter detects that the carousel is not currently filled, and adjusts the height and width of the carousel items to fill the carousel container. They are scaled up or down, meaning that values of 3000 and 2000 also could have been provided.


stretch-populate

The final resizing method behaves slightly different from the ones seen above. It is similar to stretch-gap, in that the itemSpacing values are modified, however, it is different in that when there is enough room to add a new item (or not enough item to show all items), the numItemsVisible will be increased (or decreased).

Understanding how the carousel resizes is likely better visually in this case. Below is the code for one of these carousels, as well as the resulting carousel. Again, this code presupposes that <div id="myCarousel"> already exists in the DOM, and has 9 carousel items as children.

const myCarousel = new Freighter(
  'myCarousel',
  'stretch-populate',
  'none',
  {
    numItemsVisible: 2,
    scrollBy: 3,
    itemHeight: 150,
    itemWidth: 175,
    itemSpacing: 10,
  },
);

Comparison Table

Each of the methods above impacts the properties of the carousel in some way. The table below is a quick reference as to how these properties are affected by each method.

itemWidth itemHeight itemSpacing numItemsVisible
none
stretch
stretch-gap
stretch-scale
stretch-populate
*❌ indicates that the property is modified by the resizing method.