Many times when we are designing a website, we need to stack resources or containers horizontally so they can be scrolled from left to right or right to left; however, it doesn't just have to be containers—you might want your entire website to be horizontal, a horizontal site or web.
The web is, by nature, vertical. However, there are many real-world scenarios where stacking content horizontally and allowing lateral scrolling makes perfect sense: galleries, product lists, cards, pricing plans, or even complete sites with horizontal navigation.
In my case, horizontal scrolling with CSS is something I have implemented several times in real projects. Although it usually seems trivial, the reality is that a single CSS property is not enough for it to work well, be usable, and not break on different devices.
In this guide, I'm going to teach you how to create horizontal scrolling correctly using only CSS, when to use each technique, and what errors to avoid.
What is horizontal scrolling and when to use it
Horizontal scrolling is a technique that allows the user to move from left to right within a container, instead of the classic vertical scroll.
Horizontal scroll vs vertical scroll
- Vertical scroll: ideal for long reading and traditional navigation.
- Horizontal scroll: perfect for repetitive visual elements, cards, or content consumed "in blocks."
It's not about replacing vertical scrolling, but about using it strategically.
Real-world cases where it makes sense to use it
Some scenarios where I usually use it:
- Card lists
- Carousels without JS dependencies
- Image galleries
- Mobile-first sections
- Pricing plans or comparisons
How to create horizontal scroll with CSS (classic method)
This is the simplest, most stable, and compatible technique. I've used it many times because it works without JavaScript and without weird hacks.
Although it seems obvious, forgetting one of these two properties is one of the most common mistakes.
In this post, we will see how to create horizontal or lateral scrolling on a group of containers or divs like the following:

It is actually quite simple and you do NOT need JavaScript for it to work or any "magic" plugin—just a few simple steps to keep in mind; although it's not as simple as defining a CSS rule stating that our containers should be shown horizontally and therefore scroll horizontally, we have to do a few things like the following:
- Define the height of the parent container.
- Indicate that we don't want vertical scrolling.
- Enable horizontal scrolling.
Key properties: overflow-x and overflow-y
To perform the last two steps, it is enough to apply a couple of CSS rules and their corresponding values:
overflow-x: auto;
overflow-y: hidden;- overflow-x: auto enables horizontal scroll only when necessary.
- overflow-y: hidden avoids unwanted vertical scroll.
The previous lines explain themselves; with overflow-y set to hidden, it indicates that we should hide all content that overflows our container (if we configure the CSS well, this step can be optional); with overflow-x set to auto, we indicate that we want horizontal scroll only when necessary.
CSS of the parent container for horizontal scrolling
The following CSS is used for the parent container, which is the one that will perform the horizontal displacement; we define the size and width of our parent container right away:
The parent container: size, height, and white-space
width: auto;
height: 50px;
padding: 10px;
white-space: nowrap;In general, we only set the size of our parent container and the padding; the white-space property is used to specify how to handle whitespace within the container, and with the value nowrap, we indicate that there are no line breaks or pauses; that is, all content is shown in one row, and it is the heart of our horizontal scrolling experiment.
Another important point is that we are defining a fixed container height of 50px and the container width is defined as auto, so it can grow as much as necessary.
Here is the key to the matter:
- white-space: nowrap prevents line breaks.
- The width adapts to the content.
- The height is fixed to avoid strange overflows.
In my experience, white-space: nowrap is the true heart of classic horizontal scrolling.
Child elements and why inline-block is important
Now we define the following CSS for our children, which requires no major explanation; we are simply creating small boxes:
.horizontal-scroll-contenedor div {
width: 100px;
height: 50px;
margin-right: 10px;
display: inline-block;
}Important points:
- display: inline-block keeps all elements in a single row.
- The size of the children must not exceed the height of the parent.
- The margin creates visual separation.
Practical example of horizontal scrolling with divs
As an important point, the children should have the same size or be smaller than the parent, use display: inline-block to show the content in one line, and the rest of the code is optional and can be found in the download links; finally, the HTML of our experiment:
<div class="horizontal-scroll-contenedor"><div>Container 1</div><div>Container 2</div><div>Container 3</div><div>Container 4</div><div>Container 5</div><div>Container 6</div><div>Container 7</div><div>Container 8</div><div>Container 9</div><div>Container 10</div><div>Container 11</div><div>Container 12</div><div>Container 13</div><div>Container 14</div><div>Container 15</div><div>Container 16</div><div>Container 17</div><div>Container 18</div><div>Container 19</div><div>Container 20</div></div>Full CSS based on what was explained:
.horizontal-scroll-contenedor {
width: auto;
height: 50px;
padding: 10px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.horizontal-scroll-contenedor div {
width: 100px;
height: 50px;
margin-right: 10px;
display: inline-block;
}And you can see the example below:
This pattern is simple, predictable, and easy to maintain, which is why I keep using it when I don't need advanced effects.
Horizontal scroll with Flexbox (the modern option)
Nowadays, if I have to choose, flexbox is usually my first option.
Why flex simplifies horizontal scroll
Flexbox eliminates the need for white-space and inline-block, making the code cleaner.
.flex-container { display: flex; flex-wrap: nowrap; overflow-x: auto;}And the elements:
.flex-item { flex: 0 0 auto;}- flex-wrap: nowrap prevents elements from wrapping to a new line.
- flex: 0 0 auto maintains the size of each item.
When to choose flex vs inline-block
- I use flexbox when:
- The layout is modern.
- I need vertical alignment.
- I want cleaner code.
- I use inline-block when:
- I'm looking for maximum compatibility.
- It's a very simple project.
- I don't want to depend on flex.
Scroll snapping: magnet effect when scrolling
Here we enter a more pro level.
scroll-snap-type and scroll-snap-align
These properties create the famous "magnet" effect:
.slider {
display: flex;
overflow-x: scroll;
scroll-snap-type: x proximity;
}
.card {
scroll-snap-align: center;
}This is ideal for:
- Mobile-first experiences
- Touch carousels
- "Plans" or "features" type sections
I've used it quite a bit in responsive projects because it greatly improves the experience on mobile without needing JS.
Common errors when implementing horizontal scroll
- The scroll doesn't appear
- Missing overflow-x
- The content doesn't actually overflow
- The container width is incorrect
- Elements break into several lines
- Missing white-space: nowrap
- Missing flex-wrap: nowrap
- Height and overflow issues
- Poorly defined container height
- Child elements larger than the parent
- These errors are more common than it seems; I've encountered them more than once.
Is JavaScript needed for a horizontal scroll?
In most cases: no.
CSS is:
- Faster
- Simpler
- More accessible
- More maintainable
Frequently asked questions about horizontal scroll with CSS
- Can horizontal scrolling be done with only CSS?
- Yes, and in most cases, it is the best option.
- Flexbox or inline-block?
- Flexbox is more modern and cleaner; inline-block remains valid.
- Does it work on mobile?
- Yes, especially well with touch gestures and scroll-snap.
- Does it affect SEO?
- No, as long as the content is accessible and visible.
Extra: scrolling automatically with JavaScript: .scrollLeft()
Although we said we wouldn't use JavaScript for this experiment or tutorial, we are still going to explain an extra way to enhance the previous experiment. We will simply use the .scrollLeft function to move horizontally. This is perfect if we want the scroll to move automatically; we just have to use .scrollLeft, which receives a numeric quantity as a parameter defining the number of pixels we are going to move; for example, to move 200 pixels:
// We select the container
const contenedor = document.querySelector(".horizontal-scroll-contenedor"); // We assign the displacement valuecontenedor.scrollLeft = 200;In modern JavaScript, you can use the .scrollTo() method with an options object so that the movement is not a sharp jump, but a fluid slide:
const contenedor = document.querySelector(".horizontal-scroll-contenedor");
contenedor.scrollTo({ left: 200, behavior: 'smooth' // This makes the scroll look animated});Conclusion
Horizontal scrolling with CSS is not only possible but recommended when done well. You don't need magic libraries or heavy JavaScript; just understand how overflow, display, and the layout model work.
After trying several solutions, my recommendation is clear:
- Start simple.
- Use flexbox if you can.
- Add scroll-snap only when it adds real value.
- Avoid unnecessary hacks.
I agree to receive announcements of interest about this Blog.
Learn how to create horizontal scrolling with CSS step by step, with/without JavaScript. Real-world examples, flexbox, overflow, and scroll-snap explained.