How To Create Horizontal Scrolling Containers

Colin Lord
codeburst
Published in
4 min readMar 27, 2017

--

As a front end developer, more and more frequently I am given designs that include a horizontal scrolling component. This has become especially common on mobile to help reduce the vertical height of dense pages. We’ve all seen them before. Our comp has something like this:

After building a couple of these and battling through unexpected bugs in the QA process, I wanted to find out once and for all how to create a horizontal scroller with minimal code that worked as expected across all types of devices.

Let’s first create our container and our children divs inside of it that will scroll horizontally. The HTML is pretty simple.

<div class="scrolling-wrapper">
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
<div class="card"><h2>Card</h2></div>
</div>

There are two different ways to make these divs scroll horizontally and which path you choose will probably come down to personal preference and/or browser support.

The white-space Method

Here’s all the CSS that we need. No vendor prefixes, no jQuery, just some simple use of overflow and a property you probably haven’t heard of.

.scrolling-wrapper {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;

.card {
display: inline-block;
}
}

On our container, we want to turn off vertical scrolling (overflow-y) and enable horizontal scrolling (overflow-x). Then with each card, we want to set it to display with inline-block so they all display in a row.

The line of CSS you probably are unfamiliar with is white-space: nowrap. This property is used to control how text wraps around a container. In this case, we want to disable that wrapping by using nowrap.

That’s it. Four lines of CSS properties and we’ve got a horizontal scrolling container.

As to browser support? It’s perfect. Unless you care about Internet Explorer or Edge. Microsoft says they will likely include it in a future version of Edge. But for now, it’s not available.

The Flexbox Method

Flexbox can make this work for us too.

.scrolling-wrapper-flexbox {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;

.card {
flex: 0 0 auto;
}
}

Essentially we are using flex-wrap to achieve the same effect as white-space above. There’s no real difference between what the two properties are doing.

Browser support is better for the flexbox solution. You might need to pull in some vendor prefixes for older browsers, but at least this solution works with IE and Edge.

Overflow Scrolling

Web pages on iOS scroll with momentum if you are scrolling up and down. If you flick your finger up or down quickly, the page will keep scrolling after you let go. If you reach the top or bottom of the page, the page will bounce past the end of the wrapper before bouncing back into place.

For a horizontal element, by default, we won’t have that smooth scrolling.

Luckily it’s easy to turn on. Just remember, while the prefix says webkit, this is most noticeable on iOS.

.scrolling-wrapper {
-webkit-overflow-scrolling: touch;
}

Now we have the buttery smooth scrolling on a horizontal container. Here’s an example of what that looks like:

Scroll bars

By default a container that has scrolling content will have scroll bars. Makes sense, right? But what if we don’t want that scroll bar there for UX or design purposes? Well that’s simple too. This is for webkit browsers only, however.

.scrolling-wrapper {
&::-webkit-scrollbar {
display: none;
}
}

Wrap Up

Looking at this code, this isn’t all that complicated. But it uses a number of properties that aren’t used on a regular basis and thus probably aren’t as familiar.

As this becomes a more common piece of design, it’s smart to file these snippets away because you’ll probably need them over and over. What’s great is because this is pretty simple, you can wrap this inside of a media query and display the horizontal scroller only for certain devices. There’s no headaches of jQuery or anything messy.

Update: If you’d like a CSS Grid solution, Dannie Vinther has explored that topic!

--

--

Meteorologist turned front-end engineer. Married to @katyrae87. Born in Atlanta. Educated at @FloridaState. Now living in Music City, Tennessee.