Skip to content
ThemesIonic — home
WooCommerce

Product Carousels in WooCommerce

A row of products that scrolls sideways is a CSS problem now, not a JavaScript one. Most carousel plugins load a slider library to do something the browser already does natively.

4 min read intermediate

Before installing a carousel plugin, check whether you need JavaScript at all. A horizontally scrolling row of product cards, with snapping and native momentum on touch devices, is now a handful of CSS properties applied to markup WooCommerce already produces. Slider libraries earn their place when you need synchronised pairs, infinite looping or complex responsive breakpoints. For "show eight related products in a scrolling row", they are a large dependency solving a solved problem.

What WooCommerce gives you natively

There is one carousel in core, and it is the product page image gallery: a main image with a thumbnail strip that slides. It is enabled by theme support rather than by a setting, alongside the zoom and lightbox features, which is why the same store can have a sliding gallery on one theme and a stacked column of images on another. If your gallery is not sliding, that is a theme decision, not a missing plugin.

Everything else that people call a product carousel is a product query rendered as a row:

  • Related products, upsells and cross-sells on the product page.
  • Featured, on sale, best selling or newest products on the homepage.
  • A category's products embedded in a landing page.

All three are queries WooCommerce can already run. The product shortcodes and the product listing blocks produce the grid; the only thing missing is the horizontal presentation.

The lightweight approach

Take the existing product grid markup and, instead of laying it out as a wrapping grid, lay it out as a single row that overflows horizontally with scroll snapping. The browser supplies touch momentum, keyboard scrolling, a scrollbar, and correct behaviour when the user prefers reduced motion — all things a library has to reimplement, usually incompletely.

What you give up is autoplay, dot navigation and looping. Autoplay is a liability on a shopping row anyway, since it moves the thing the customer was reaching for. Arrow buttons can be added later with a few lines of script that scroll the container, without adopting a slider framework to get them.

This is ordinary CSS applied to a container class, so it belongs with the rest of your custom CSS rather than in a plugin. The related products section is the easiest place to start, because WooCommerce already outputs it with predictable classes and filters exist for changing how many products it shows and in how many columns.

Requirement Native CSS row Carousel plugin
Sideways scrolling row of products Yes Yes
Snapping and touch momentum Yes, from the browser Reimplemented
Previous and next buttons Small script Yes
Different card counts per breakpoint Yes Yes
Infinite loop No Yes
Autoplay No Yes, usually on by default
Synchronised carousels No Yes
Editing in a page builder No Yes

The realistic reason to buy is the last row. If the person maintaining the site works in a page builder, a carousel widget they can configure visually is worth more than a technically leaner solution they cannot edit.

The traps, in order of how often they bite

Layout shift. A slider that rearranges markup after load is one of the most reliable ways to produce a bad cumulative layout shift score, because the row collapses from a tall stack to a short strip while the page is being read. Reserve the height in CSS.

Images inside slides. Lazy loading and carousels interact badly: off-screen slides may never load, or every slide loads at once and the row becomes the heaviest thing on the page. Confirm which is happening, and make sure the cards are using the catalogue thumbnail rather than a full-size image — the wrong product image size in a ten-card row is a multiplied mistake.

Duplicate libraries. Themes, page builders and carousel plugins each tend to bring their own slider script. Three of them on one page is common and entirely invisible until you look at the network panel. This is a straightforward contributor to render-blocking resources.

Keyboard and screen reader access. Cards that scroll out of view must still be reachable by tab, and focusing a card must bring it into view rather than scrolling the row invisibly. Test this before launch; it is quick and it is nearly always broken.

What to do

Start with the related products row, restyle it as a scroll-snapping row, and look at it on a phone. If that solves the requirement, you have added no scripts, no layout shift and nothing to maintain through the next theme update. Reach for a plugin only for the specific features in the lower half of that table, and if you do, put a real product on the first card, because that is the one everybody sees.

Frequently asked

It has a slider for the images on a single product page, enabled through theme support, but nothing that turns a list of products into a sideways-scrolling row. That part is left to the theme, a page builder or a plugin.
Because the markup renders as a plain stacked list until the slider script initialises and rearranges it. Reserving the row's height in CSS, and hiding the container until initialisation, both remove the jump; the first is preferable because it does not depend on the script arriving.
They are neutral for browsing rows like related products and poor as a substitute for a homepage hero. The safe assumption is that whatever sits on the first slide is what most visitors will see, so never hide anything important on slide three.

Related guides