Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is overflow-y: hidden creating a horizontal scroll bar in my flex layout?

Tags:

html

css

flexbox

I have two panels side by side. The right-hand one contains species names, which should not wrap (they're small enough to occupy only a small part of the screen). The left-hand panel contains more things, and occupy most of the screen. Here's my code.

html,body {
  height: 100%;
}
body {
  display: flex;
  margin: 0;
  overflow-y: hidden;
}
#left {
  background-color: skyblue;
  flex-grow: 1;
  padding: 1em;
}
#right {
  background-color: indianRed;
	white-space: nowrap;
  padding: 1em;
  display: flex;
  flex-direction: column;
}
<div id='left'>
Some text wide enough to compete with the red panel -- some more words needed.
</div>
<div id='right'>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
</div>

When there's no scrollbar, the width of the right-hand panel is correct. But as soon as I add a vertical scrollbar (overflow-y: auto), it's width gets much smaller, creating also a horizontal scrollbar. Why? And how to solve it? I only want the vertical scrollbar. The width of the panel should be enough to contain all the words on it.

html,body {
  height: 100%;
}
body {
  display: flex;
  margin: 0;
  overflow-y: hidden;
}
#left {
  background-color: skyblue;
  flex-grow: 1;
  padding: 1em;
}
#right {
  background-color: indianRed;
  white-space: nowrap;
  padding: 1em;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
<div id='left'>
Some text wide enough to compete with the red panel -- some more words needed.
</div>
<div id='right'>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
<p>Some names.</p>
<p>Some names a little larger.</p>
</div>
like image 526
Rodrigo Avatar asked Dec 10 '19 12:12

Rodrigo


2 Answers

Your current flex properties is as follow :

div#left

flex-grow:1;
flex-shrink:1;
flex-basis:auto;

This means:

The div's width will be content first flex-basis:auto; then fill the remaining space flex-grow:1;

div#right

flex-grow:0;
flex-shrink:1;
flex-basis:auto;

This means:

The div's width will be content first flex-basis:auto; And shrink to fit flex-shrink:1;

This is why you see horizontal scrollbar when the vertical scroll is added, because it eats from the overall width.


Solution #1

flex-basis:0; on the left div which will make it fill the remaining space first then lay down the content

html,
body {
  height: 100%;
}

body {
  display: flex;
  margin: 0;
  overflow-y: hidden;
}

#left {
  background-color: skyblue;
  flex-grow: 1;
  flex-basis: 0;
  padding: 1em;
}

#right {
  background-color: indianRed;
  white-space: nowrap;
  padding: 1em;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
<div id='left'>
  Some text wide enough to compete with the red panel -- some more words needed.
</div>
<div id='right'>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
</div>

Solution #2

flex-shrink:0; on the right div which will prevent it from shrinking

html,
body {
  height: 100%;
}

body {
  display: flex;
  margin: 0;
  overflow-y: hidden;
}

#left {
  background-color: skyblue;
  flex-grow: 1;
  padding: 1em;
}

#right {
  background-color: indianRed;
  white-space: nowrap;
  padding: 1em;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
<div id='left'>
  Some text wide enough to compete with the red panel -- some more words needed.
</div>
<div id='right'>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
</div>

Issue with this solution is that if the content in the left div is too long there will be overflow

html,body {
  height: 100%;
}
body {
  display: flex;
  margin: 0;
  /* removed to illustrate the problem */
  /* overflow-y: hidden; */
}
#left {
  background-color: skyblue;
  flex-grow: 1; 
  padding: 1em;
}
#right {
  background-color: indianRed;
  white-space: nowrap;
  padding: 1em;
  display: flex;
  /* if you remove this there will be no overflow because the right div will shrink to fit*/
  flex-shrink:0; 
  flex-direction: column;
  overflow-y: auto;
}

#left>div{
    /* I eyeballed this value to fit the snippet in SO*/
    width:500px; 
    background-color:Red;
    height:100px;
}
<div id="left">
  <div>
    <div>
    </div>
  </div>
</div>
<div id="right">
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
  <p>Some names.</p>
  <p>Some names a little larger.</p>
</div>
</body>
like image 122
Nothing Mattress Avatar answered Nov 05 '22 09:11

Nothing Mattress


Its because of long text inside your div and you set white-space: nowrap; which prevent it to overflow

Use

#right {
    white-space: normal;
}
like image 42
Awais Avatar answered Nov 05 '22 09:11

Awais