The freedom that Freighter provides naturally has a few cautions
to be aware of. With so many properties that work together, it is
easy to accidentally create a situation that is not intended.
Reserved IDs and Classnames
In order to make Freighter work, a number of custom HTML and CSS
IDs and classnames are used internally. In order to prevent any
conflicts, it is recommended that you do not use any of the
following IDs or classnames in your HTML. If you are
experiencing any odd behavior, check to make sure that you are
not already using any of these in your own HTML.
Reserved IDs:
#freighter-carousel-container-*
#freighter-carousel-item-container-wrapper-*
#freighter-carousel-item-container-*
#freighter-carousel-item-*-*
#freighter-carousel-arrow-left-*
#freighter-carousel-arrow-right-*
* Note that the asterisk (*) in the above IDs will be replaced
with some number, so both
#freighter-carouse-item-2-1 and
#freighter-carousel-item-4-3 are potentially unsafe
IDs to use.
Reserved classes:
.freighter-carousel-container
.freighter-carousel-item-container-wrapper
.freighter-carousel-item-container
.freighter-carousel-item
.frieghter-carousel-item-dummy
.freighter-carousel-arrow-left
.freighter-carousel-arrow-right
Duplicate Carousel Items
As is discussed in the
wrapping page of
the documentation, there are a number of wrapping methods that
cause carousel items to 'wrap' from end to end. In certain
situations, such as when the carousel contains fewer items than
the numItemsVisible property, empty spaces will be
filled with duplicate items.
If your carousel is set up in a way that makes this possible,
and elements that are children of the carousel items will
also be duplicated, potentially duplicating IDs. Take
the carousel below as an example. If you inspect the carousel
items, you will notice that the id attribute of
some are duplicated.
1
2
For the most part, this shouldn't cause any issue. If, however,
you write code that assumes only one element in the DOM will
have a given ID, this may cause that code to break. Use your
best judgement when pairing a wrapping method with carousel
items that have functionality dependent on their IDs.
Freighter and the DOM
When a Freighter carousel is constructed, more elements are
created than just the container and children (this becomes more
obvious when you see the number of
reserved IDs and classnames
that exist)! Feel free to inspect the carousel in your browser's
developer tools to see some of these.
It is important to point out that you should not add or
remove any styles, event listeners, or children from any of
these elements. These are all maintained by Freighter, and
changing them in any way risks breaking the carousel. If you are
feeling brave, and feel as though you understand how something
has been implemented, just be aware that you may end up breaking
something down the line.
Changing Styles
One important design decision made was to ensure that elements
created by you are not altered in any way: both the top-level
carousel container
<div id="carousel-1"
class="freighter-c"></div>
as well as all carousel items
<div class="ci"><p>1</p></div>
remain untouched, as indicated by a lack of inline styles. This
gives the programmer (mostly) total freedom to style each of
these components of the carousel as they wish. The only warning
that is associated with this feature is to
avoid styling relative to the carousel items or containers
. Applying CSS styles that impact parents of the carousel items
or children of the carousel container with selectors such as
>, ~ or instances of
has() may end up overriding essential styles to
internal Freighter elements.
In general, it is advised to give carousel elements a common
class for styling, and apply your CSS styles to the classes
themselves rather than parents or children of elements.
Transition Timing Functions
Freighter provides you with the ability to select your own
custom CSS transition timing functions. These can be as simple
as linear or as complex as
cubic-bezier(), but the more complex come with an
important caution.
Internally, Freighter only inserts as many carousel items as
necessary; if you create a carousel with 15 items but set
numItemsVisible to 3, then the other 12 items are
stored in memory until they should come into view. For this
reason, some cubic-bezier() functions that go
beyond the items visible on the screen may result in blank spots
in the carousel. The code below demonstrates a dangerous
carousel whose transition timing function goes beyond the
visible items to an extreme degree.
Notice that with a function this extreme, at first the previous
items show up properly. Scrolling from items 3 on demonstrates
that only one previous item is added to either side when
transitioning, which also happens to be the
scrollBy value for this carousel.
In fact, below is a breakdown of how many carousel items are
actually exist in the DOM at the stages of the carousel
transition:
Before Transition:numItemsVisible carousel items loaded.
Only need to load those that are currently visible in the
carousel.
During Transition:numItemsVisible + (2 * scrollBy) carousel items
loaded.
scrollBy additional items are added to each
side during a scroll in either direction.
After Transition: numItemsVisible carousel items loaded.
The extras are removed when the transition completes.
In the example above, then, we can only ever assume that 1 extra
carousel item will be inserted into the carousel on either side
during transitions. As long as the
cubic-bezier() function does not expose more than
one extra carousel item, this shouldn't be a problem.
Changing from wrap-smart to
wrap-simple
Both of the wrapping methods ensure that there are never any
empty spots in a carousel; if there normally would be with
wrapping method none, they are filled with carousel
items from the start of the container. Nothing new here.
wrap-smart, however, modifies the amount that will
be scrolled in order to preserve the absolute ordering of the
carousel items - an item with a lower index will never be shown
after an item with a higher index. Again, this is all understood
by the definition of the wrapping method.
There is one situation in which these rules are in
contradiction: that is, when numItemsVisible is
larger than the total number of carousel items, as
shown below:
Clearly, the above carousel could not use
wrap-smart, as the absolute ordering of the items
would not be preserved. What happens, then, if you try to use
this wrapping method in a situation like this? The carousel
below is the result of such an attempt:
1
2
3
Looks the same, and if you try scrolling, you will see it
behaves the screen. This is because the carousel has been
converted to use wrap-simple! Check the console to
see the warning message that displays when this occurs; it looks
something like this:
Carousel ID "carousel-4": Cannot allow smart wrapping if the
carousel has fewer items than items visible. Setting wrapping
method to 'wrap-simple'.
This may occur with other combinations of carousel properties.
What if you initially keep numItemsVisible less
than the total number of carousel items, but one of these
changes later? Suppose you remove carousel items, or decrease
the numItemsVisible, or use the resizing method
stretch-populate which can increase the
numItemsVisible? In all of these cases (and any
other you can think of), when it is detected that the absolute
ordering of carousel items cannot be maintained, the carousel is
automatically converted to use wrap-simple
Check out the following example. After you remove an item from
the carousel, you will notice that an absolute order cannot be
maintained, so the wrapping method switches and a warning is
output to the console.
1
2
3
4
As long as you are cautious about changing the
numItemsVisible property, this should not be a
problem.