DEV Community

Cover image for React Carousel Component "with Batteries Included"
Yifan Ai
Yifan Ai

Posted on


React Carousel Component "with Batteries Included"

react-gallery-carousel controlled by touch

Demo: (or

react-gallery-carousel cover image


I have used and carefully analysed a lot of carousel/slider components. I summarised that their issues are:

  1. Some of them do not move the slide as the user swipes on the slide.
  2. Most of them do not support mouse dragging to move to the previous or the next slide. With the ones those support mouse emulation, some of them do not properly handle the case where the mouse leaves the carousel, which allow the user to continuously control the carousel.
  3. Most of them do not support keyboard navigation (i.e. left, right and tab key).
  4. Most of them cannot be maximised to fullscreen/modal/lightbox. With fullscreen, there is the issue of browser compatibility, i.e. iOS Safari on iPhone does not support the fullscreen API.
  5. Most of them do not have an easy solution for building thumbnails. With the ones those have thumbnails, most of the thumbnails cannot be freely scrolled which lead to poor user experience. In addition, most of the thumbnails cannot be lazy loaded.
  6. Most of them cannot lazy load (and preload) images. With the ones those can lazy load, most of them have transition that traverses the intermediate images when the user goes to a distant slide, which defeat the purpose of lazy loading.
  7. Some of them cannot autoplay. With the ones those can autoplay, they cannot auto pause. For example, when the user hits another tab or goes to another app, the autoplay on those carousels do not pause.
  8. Most of them do not respect the reduced motion settings by the user.
  9. Most of them disregard the velocity of the swipe and just set a constant transition duration.
  10. Some of their carousels will be in different sizes when the images/slides inside are in different sizes. Some of their transitions are bumpy when their images/slides are in different sizes.
  11. Most of them do not support custom elements in a slide.
  12. Most of them cannot be set to display in Right-to-Left (RTL).
  13. Some of them disable pinching to zoom, while some others glitch when pinching with 2 fingers. Besides, when the window is zoomed in, most of them still detect for touch swiping to move to the previous, or the next slide, while the intention of most users in this scenario is panning to see other parts of the current slide.
  14. Some of them will cause the slides to stuck its position on window resize or on mobile device orientation change, until another user interaction.
  15. Some of them can only have predetermined images (i.e. before the carousel component mounts).
  16. Most of them do not provide a solution for fallback image (for when an image is not available).
  17. Some of them get zoomed in when the user double taps on the control, while the intention of most users in this scenario is to quickly go to the next after the next slide.
  18. Some of them remove the left or right button to indicate that there are no more slides in that direction. However, user is likely to click that spot where the button used to be, which causes undesired behaviours e.g. clicking on a link or button which is also at that spot.
  19. Some of them use the method of cloning the first, and the last slide to achieve looping (or infinite mode). I think that method is not great semantically.
  20. Some of them cannot distinguish a vertical swipe from a horizontal swipe, so that a not exactly vertical swipe moves the slides slightly horizontally; and a not exactly horizontal swipe moves the (document) page slightly vertically.


I wanted to write my own detail-oriented and exquisite carousel component that is easy to use yet solves/supports all these things above under the hood. πŸ€“

I wanted to take my understanding of JavaScript events, DOM manipulation, browser APIs, cross-browser compatibility and performance debugging to the next level. πŸ€“

I wanted to master React functional components, hooks, custom hooks and reconciliation. πŸ€“

I wanted to learn more, place more care and attention to accessibility. I want to give focus outlines to the right users, support keyboard navigation, support screen reader, and follow W3C accessible carousel tutorials.


My carousel should support: touch, mouse emulation, keyboard navigation, modal (lightbox), thumbnails, autoplay (and auto pause), RTL (right to left for internationalisation), image lazy loading (and preloading), responsive images, fallback image, reduced motion settings, instantaneous velocity detection, responsive design, images with any sizes, custom elements in a slide, pinch to zoom, customisation and great accessibility. 😎

(e.g. To solve the last issue (#20) in the list above, my carousel should be able to detect a mostly vertical swipe and then fix the slides horizontally in the carousel. βœ…
It should also be able to detect a mostly horizontal swipe and then fix the carousel vertically in the page. βœ…)


Demo: (or

react-gallery-carousel controlled by touch

react-gallery-carousel controlled by mouse

Lighthouse report on react-gallery-carousel's demo site

Demo: (or

I carefully handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. πŸ‘¨πŸ»β€πŸ’»

react-gallery-carousel not maximised

react-gallery-carousel being maximised

Everyone is welcome to come and ask questions, find and report issues, make pull requests and suggestions! 😊

Demo: (or
Buy me a coffee to support me:

Top comments (1)

miketalbot profile image
Mike Talbot ⭐

That's a really nice component, one question, is it possible to apply an easing function to the slide movement so that it slows into place?

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.