If you just want to see the demo and code, you can jump straight to the CodePen. 💅
Our goal was to have a flexible component which can embed pretty much any HTML, as well as give the possibility to display multiple items on each slide. The number of items per slide would be flexible per usage as well as per responsive breakpoint.
On small and medium screens, the carousel should show the list of items without any controls, as the user would swipe horizontally to go through them. All we need is to show a small part of the next slide on the right side as a cue to swipe left. Here is an example from our new and pretty homepage:
On large screens, control arrows are shown on the sides and the user can click them to go through the slides one by one.
Benefits and limitations
Before we dig into the code, I would like to share some thoughts on this approach. In the past we used a few dedicated jQuery plugins to build carousels. These solutions are very quick to implement, but come with problems: heavy resources to load, most functionalities they bring won’t be used in your application and some of their behaviours and styles can be difficult to override.
Instead, we can have a very lightweight and simple tool that fits exactly our need. However, because our component functions based on a static language like CSS, we are limited to set a maximum number of slides, which we set to 10. I actually think this limitation is a good thing as it sets a constraint that shouldn’t be exceeded anyway. If you have a carousel with more than 10 slides on your website and expect users to navigate through them, maybe you’re using the wrong component and should re-consider your user experience.
The carousel’s markup is composed of 3 parts:
- The activators: a number of hidden radio buttons that control which slide is shown on large screens. Activators need to be at the top of the markup as we will use the general sibling combinator in CSS
~to move the slider based on which activator is selected.
- The track: the container of all the slides. We’re calling it a track as the slides are horizontally aligned, with an hidden overflow. We will be using the
transformCSS property to move the track to the right position based on the current checked activator.
To function, the carousel needs as many activators and control arrows as the number of slides on large screens.
For our demo, we will display 7 items in the carousel, using the same layout as described by the mockup above: 1 item per slide on small screens, 2 on medium screens and 3 on large screens. We use a separate helper class for each specification on every item of the carousel:
carousel__item — mobile-in-1,
carousel__item — tablet-in-2,
carousel__item — desktop-in-3
No JS, no problems
In our example, we start with the styles for large screens, although the same result can be achieved using a mobile-first approach.
To have the carousel working, the key is to:
.carousel__itemelements to display in a single line using
display: inline-flex;and adding
white-space: nowrapon the
- Hide anything beyond the carousel by setting
- Using a
forloop in your favourite preprocessor, the
nth-of-typeselector and the
~combinator, display the
.carousel__controlsbased on the position of the currently checked
- Using the same loop as above, set a translation of the
Swipe left or right
On medium and small screens, we choose to hide the controls and let the user swipe through the carousel items. To do this, we simply need to undo some of the styles previously defined. Then we simply need to:
.carousel__trackto display using
- Define the size of the carousel elements, using help classes generated by another
forloop. We use a reference of
90%of the parent element’s width in order to have the next element visible on the right side of the screen.
Check out the CodePen below or the component on our lovely design system.
If you have any questions or thoughts on our approach, we’d love to hear them!