DEV Community

Cover image for CSS Horizontal Scroll: a Step-by-Step Guide
Jesse Wei
Jesse Wei

Posted on

CSS Horizontal Scroll: a Step-by-Step Guide

Bored with all the vertical scrolls in websites? Today, let's build a simple horizontal scrolling page using CSS.

Overview

The key concept is to rotate the container 90 degrees and then rotate its child elements 90 degrees backwards to counter the container's rotation.

key concept is to rotate the container 90 degrees and then rotate its child elements 90 degrees backwards

Here is a live demo of what we are going to build.

You can find the complete code here.

HTML

With that in mind, we can build it out really fast. Let's begin with HTML.

<div class="container">
  <div>
    <img src="./images/image1.jpeg" alt="" />
    <p>image 1</p>
  </div>
  <div>
    <img src="./images/image2.jpeg" alt="" />
    <p>image 2</p>
  </div>
  <div>
    <img src="./images/image3.jpeg" alt="" />
    <p>image 3</p>
  </div>
  <div>
    <img src="./images/image4.jpeg" alt="" />
    <p>image 4</p>
  </div>
  <div>
    <img src="./images/image5.jpeg" alt="" />
    <p>image 5</p>
  </div>
  <div>
    <img src="./images/image6.jpeg" alt="" />
    <p>image 6</p>
  </div>
  <div>
    <img src="./images/image7.jpeg" alt="" />
    <p>image 7</p>
  </div>
  <div>
    <img src="./images/image8.jpeg" alt="" />
    <p>image 8</p>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS

CSS code is a bit more complicated but the concept has been covered above. We just need to code carefully and incremently.

Let's start with the big picture and give the page a structure.

.container {
  /* 
  Width and height will swap after rotation. 
  To make the container as wide as the screen after rotation,
  we need to set its initial height to 100vw.
  */
  width: 500px;
  height: 100vw;
}
.container div {
  width: 100%;
  height: 500px;
}
img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
Enter fullscreen mode Exit fullscreen mode

Now, the page should look like this. It's still far from what we want.

page after css step 1

Let's rotate the container 90 degrees and its children 90 degrees backwards.

.container {
  ...
  /*
  translateY(-500px) makes the container align
  to the left of the screen.
  */
  transform: rotate(-90deg) translateY(-500px);
  transform-origin: top right;
}
.container div {
  ...
  transform: rotate(90deg);
}
Enter fullscreen mode Exit fullscreen mode

Now it's closer to what we expect but it cannot scroll horizontally yet.

page after css step 2

To make it horizontally scrollable is as easy as adding two lines of code.

.container {
  ...
  overflow-x: hidden;
  overflow-y: auto;
}
Enter fullscreen mode Exit fullscreen mode

We are almost done except some clean-ups and polishing. Let's add the following code.

body {
  margin: 0;
}
/*
To hide the scroll bar.
*/
::-webkit-scrollbar {
  display: none;
}
* {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
img {
  ...
}
.container div {
  ...
  position: relative;
  margin: 10px 0;
}
.container div:first-child {
  margin: 0;
}
p {
  padding: 10px;
  background: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Enter fullscreen mode Exit fullscreen mode

The final page should look like this and scroll horizontally.

final page

Here is the complete CSS code.

body {
  margin: 0;
}
::-webkit-scrollbar {
  display: none;
}
* {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.container {
  width: 500px;
  height: 100vw;
  transform: rotate(-90deg) translateY(-500px);
  transform-origin: top right;
  overflow-x: hidden;
  overflow-y: auto;
}
.container div {
  position: relative;
  width: 100%;
  height: 500px;
  transform: rotate(90deg);
  margin: 10px 0;
}
.container div:first-child {
  margin: 0;
}
p {
  padding: 10px;
  background: white;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Enter fullscreen mode Exit fullscreen mode

Notes

  • In this example, we used squared child elements (500 * 500 images) and there is a reason for this. If the width:height ratio was not 1:1, we would have to work out how much to offset the child elements after rotation so that they do not overlap each other.
  • For such cases and more advanced functionalities or effects, you would want to write some javacript code.

Top comments (0)