A mobile friendly and progressive enhanced image carousel
- Responsive and mobile-friendly
- Fullscreen mode
- Touch gestures and mouse dragging
- Accessible with keyboard and screen reader
- Clean and semantic HTML
- Works with images of any size
- Hardware accelerated animations (using CSS transform)
- Lightweight (~10kb minified)
- No JQuery dependency
- Browser support:
- Browsers supporting classList and CSS transforms: basically IE10+ and all modern browsers.
- On older browsers (and while JavaScript is loading), the browser will render an ordinary grid of images. Clicking an image will open the high resolution image.
Progressive Carousel has a consistent user experience across different screen sizes, and on portrait/landscape orientation: there is no predefined amount of images for each breakpoint.
On smaller screens, a tiny bit of the next and previous image is visible. This gives the user a hint that he can swipe the images left and right.
Swiping is implemented using the Touch API (and not the more generic, but less supported, Pointer Events API). When your browser doesn't support the Touch API, you can still control the carousel with the buttons.
On larger screens, more images are visible in the image strip. Although the carousel can be nested inside a single column layout, it is recommended to show the images on full width of the page, maximizing available screen space.
The next/previous buttons and the first image in the strip are focusable with the keyboard (TAB
key). Opening the first image with the keyboard will toggle fullscreen mode. While in fullscreen mode, users can press ESC
to exit and the arrow keys (← →
) to cycle through the images.
The carousel uses the Fullscreen API. For browsers not supporting the Fullscreen API, the carousel will be shown in 100% width/height of the browser window.
- A build system that can transpile ES6 and bundle modules. If you don't have this yet, I recommend the rollup bundle and watch recipe from De Voorhoede.
- Minimum of 5 images
- Images must have identical aspect ratio
Get started by adding the following HTML to your page.
- Data-attributes (e.g.
data-carousel
) are used by JavaScript to interact with the DOM. Keep them. - Classes are only used for styling. Customize them as you like.
<div class="carousel" data-carousel>
<button class="carousel-close"
data-carousel-close>Close</button>
<button class="carousel-previous"
data-carousel-previous
aria-label="Previous"></button>
<ul class="carousel-list"
data-carousel-list>
<li class="carousel-item" data-carousel-item>
<a class="carousel-anchor"
href="image-xl.jpg"
data-carousel-anchor>
<img class="carousel-img"
src="image-m.jpg"
srcset="image-s.jpg 300w,
image-m 600w,
image-l.jpg 968w,
image-xl.jpg 1920w"
sizes="(min-width: 1170px) 968px, 85vw"
alt="Example image 1"
data-carousel-img>
</a>
</li>
<!-- <li>'s for remaining images here -->
</ul>
<button class="carousel-next"
data-carousel-next
aria-label="Previous"></button>
</div>
Explanation:
<a>
-
href
: url of high resolution image.This allows the user to navigate to the high resolution image when the carousel is not enhanced with JavaScript. When? While JavaScript is loading, on browsers not meeting the minimum criteria or when JavaScript is disabled. Everyone has Javascript, right?
-
<img>
src
: url of the fallback image for browsers not supporting 'srcset'.- In fullscreen mode, the carousel will replace the
src
value with the url of the image with the highest resolution (as specified insrcset
). This allows browsers not supportingsrcset
to still show high resultion images in fullscreen mode.
- In fullscreen mode, the carousel will replace the
srcset
: list of responsive images and their natural width, so that browsers can choose the appropriate image (srcset and sizes explanation).- The example lists 4 images, but any number works. The browser will choose to load an image based on resolution and device-pixel-ratio. Providing enough images can save the user precious time and bandwidth.
- The example lists
300w
,600w
,968w
and1920w
as natural widths, but the carousel accepts images with any natural width.
sizes
: width of the image when the condition matches.- In the example we tell the browser to show each image at
85vw
width, except for breakpoints above1170px
, in which case the browser should render the image at968px
width. This means you don't have to configure the exact number of visible images per breakpoint. - In fullscreen mode, the carousel will set the
sizes
attribute value to100vw
, so that the browser can choose the appropriate fullscreen image. When fullscreen is closed, the sizes attribute is restored to the original value.
- In the example we tell the browser to show each image at
You can find boilerplate CSS here to get you started.
Typical things you may want to customize:
- the speed and type of animations
- next/previous/close button styles
- layout of the thumbnails when the carousel is not enhanced with JavaScript.
The CSS file contains vendor prefixes. Consider using a build system with autoprefixer to add them automatically.
- First, import the JavaScript module:
import Carousel from 'progressive-carousel';
- Then initialize all carousels (more than 1 is allowed):
Carousel.initializeAll();
When the carousel has been initialized, the images should be positioned side by side (like a 'film strip') and no longer in a grid.
By default, all carousels on the page are initialized. Optionally, you can provide a DOM element to scope the context where carousels appear in, e.g.:
// initialize all carousels inside `#sidebar`
const sidebar = document.getElementById('sidebar');
Carousel.initializeAll(sidebar);
- Lazy loading of images
- Loading indicator (in particular in fullscreen)
Not planned:
- Captions
- Breadcrumbs / circles / progress indicators
Created and maintained by reinout.com