Scroll-x as overflow not working - shows scrollbar for y instead

Viewed 1308

I'm trying to understand why I cannot scroll horizontally to see the other pink thumbs. I added an overflow of scroll-x to the thumbs container and thought it would allow me to scroll horizontally to see the other thumbs; instead, it only scrolls vertically.

Can someone explain why it doesn't scroll horizontally? thanks a million

#content-wrap {
  background: lightgreen;
  width: 300px;
  height: 300px;
}
#main-image {
  background: cyan;
  width: 300px;
  height: 250px;
  float: left;
}
#thumbs-wrap {
  background: orange;
  width: 300px;
  height: 50px;
  float: left;
  overflow-x: scroll;
}
.thumb {
  background: pink;
  box-sizing: border-box;
  width: 75px;
  height: 50px;
  border: 2px solid grey;
  float: left;
}
<div id="content-wrap">
  <div id="main-image"></div>
  <div id="thumbs-wrap">
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
  </div>
</div>

2 Answers

It's because your #thumbs-wrap has fixed width, and it's not enough to keep all child elements in one row or add horizontal scrollbar. As an easy solution, you can wrap all child elements inside another one div and give extra-width to it. Here is an example:

#content-wrap {
  background: lightgreen;
  width: 300px;
  height: 300px;
}
#main-image {
  background: cyan;
  width: 300px;
  height: 250px;
  float: left;
}
#thumbs-wrap {
  background: orange;
  width: 300px;
  height: 50px;
  float: left;
  overflow-x: scroll;
}
#thumbs-inner-wrap {
  width: 1000px;
}
.thumb {
  background: pink;
  box-sizing: border-box;
  width: 75px;
  height: 50px;
  border: 2px solid grey;
  float: left;
}
<div id="content-wrap">
  <div id="main-image"></div>
  <div id="thumbs-wrap">
    <div id="thumbs-inner-wrap">
      <div class="thumb"></div>
      <div class="thumb"></div>
      <div class="thumb"></div>
      <div class="thumb"></div>
      <div class="thumb"></div>
      <div class="thumb"></div>
    </div>
  </div>
</div>

HTML elements will usually wrap to new lines when there is no more horizontal space. That's why you get a vertical scrollbar even if you set overflow-x: auto. You can use CSS flexbox to override this behavior without adding any more elements. Add the following to your CSS:

#thumbs-wrap {
    display: flex;
    flex-wrap: nowrap;
}
.thumb {
    flex: 0 0 auto;
}

How does this work?

flex-wrap:nowrap makes sure we force the child elements to stay on one line, and not wrap to new lines.

Now usually this might make the flex items shrink or grow to fit the horizontal space of their parent element. We can control this by controlling their sizes.

The flex property with three values is shorthand for flex: flex-grow flex-shrink flex-basis.

With flex-grow and flex-shrink set to 0, the flex items are not allowed to either grow/expand or shrink to fit the space of the container.

flex-basis:auto makes sure the flex items are sized exactly the way we have already sized them in our CSS.

Together these rulesets forces the flex items (.thumb) to be aligned horizontally, not wrap to a second line and to remain their original size. This will force a horizontal scrollbar to appear on the #thumbs-wrap element.


You can see how this works out together with your code:

#content-wrap {
  background: lightgreen;
  width: 300px;
  height: 300px;
}
#main-image {
  background: cyan;
  width: 300px;
  height: 250px;
  float: left;
}
#thumbs-wrap {
  background: orange;
  width: 300px;
  height: 50px;
  float: left;
  overflow-x: scroll;
  display: flex;
  flex-wrap: nowrap;
}
.thumb {
  flex: 0 0 auto;
  background: pink;
  box-sizing: border-box;
  width: 75px;
  height: 50px;
  border: 2px solid grey;
  float: left;
}
<div id="content-wrap">
  <div id="main-image"></div>
  <div id="thumbs-wrap">
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
    <div class="thumb"></div>
  </div>
</div>

Related