Reputation: 927
Could you give me an explanation of what is going here? (If it's possible attach links to the CSS spec)
When I set flex-shrink to 0 on #grid-container (flex: 1 0 auto
), there appears a scroll bar for the whole page
But when I set flex-shrink to 1 on #grid-container (flex: 1 1 auto
), the bar scroll bar appears only for the #grid-container
In the code snippet below flex-shrink on #grid-container is set to to 0 (flex: 1 0 auto
). Change it to 1(flex: 1 1 auto
) to see the difference
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
}
#header {
background-color: brown;
flex: 0 0 100px;
}
#grid-container {
flex: 1 1 auto;
display: grid;
overflow: hidden;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
}
#grid-item {
grid-column: 1/2;
grid-row: 1/2;
overflow: auto;
}
#list {
overflow: auto;
}
#list-item {
font-size: 140px;
}
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
</head>
<body>
<div id="header"></div>
<div id="grid-container">
<div id="grid-item">
<div id="list">
<div id="list-item">1</div>
<div id="list-item">2</div>
<div id="list-item">3</div>
<div id="list-item">4</div>
<div id="list-item">5</div>
<div id="list-item">6</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 5
Views: 89
Reputation: 274384
By setting flex-shrink:1
(the default value) you allow your element to shrink inside its flex container and since you set the body
(the flex container) to be height:100%
it will shrink to fit inside it creating the scroll bar only on the container because its content is overflowing. Te be more accurate the scroll bar is on #grid-item
and not the container which is logical since this one is having overflow:auto
.
Add border to better see this:
html {
height: 100%;
background:#fff;
}
body {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
background:red;
}
#header {
background-color: brown;
flex: 0 0 100px;
}
#grid-container {
flex: 1 1 auto;
display: grid;
overflow: hidden;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
border:5px solid green;
}
#grid-item {
grid-column: 1/2;
grid-row: 1/2;
overflow: auto;
border:5px solid blue;
}
#list {
/* overflow: auto; not needed*/
border:5px solid yellow;
}
#list-item {
font-size: 140px;
}
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
</head>
<body>
<div id="header"></div>
<div id="grid-container">
<div id="grid-item">
<div id="list">
<div id="list-item">1</div>
<div id="list-item">2</div>
<div id="list-item">3</div>
<div id="list-item">4</div>
<div id="list-item">5</div>
<div id="list-item">6</div>
</div>
</div>
</div>
</body>
</html>
You can also set overflow:auto
to the container and you will have the scroll on the container and almost the same result
html {
height: 100%;
background:#fff;
}
body {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
background:red;
}
#header {
background-color: brown;
flex: 0 0 100px;
}
#grid-container {
flex: 1 1 auto;
display: grid;
overflow: auto;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
border:5px solid green;
}
#grid-item {
grid-column: 1/2;
grid-row: 1/2;
border:5px solid blue;
}
#list {
/* overflow: auto; not needed*/
border:5px solid yellow;
}
#list-item {
font-size: 140px;
}
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
</head>
<body>
<div id="header"></div>
<div id="grid-container">
<div id="grid-item">
<div id="list">
<div id="list-item">1</div>
<div id="list-item">2</div>
<div id="list-item">3</div>
<div id="list-item">4</div>
<div id="list-item">5</div>
<div id="list-item">6</div>
</div>
</div>
</div>
</body>
</html>
By disabling the shrink, the element and its content will overflow outside the body and also the html which will create a scroll bar on the viewport to be able to see the overflowing content. Adding overflow:auto
is useless in this case since the parent height is the same as the content height.
Add background to body/html elements to better see the overflow when disabling the shrink
html {
height: 100%;
background:#fff; /*to stop the propagation of the red color*/
border:5px dotted purple;
}
body {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
background:red;
}
#header {
background-color: brown;
flex: 0 0 100px;
}
#grid-container {
flex: 1 0 auto;
display: grid;
overflow: hidden;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
border:5px solid green;
}
#grid-item {
grid-column: 1/2;
grid-row: 1/2;
overflow: auto;
border:5px solid blue;
}
#list {
/* overflow: auto; not needed*/
}
#list-item {
font-size: 140px;
}
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
</head>
<body>
<div id="header"></div>
<div id="grid-container">
<div id="grid-item">
<div id="list">
<div id="list-item">1</div>
<div id="list-item">2</div>
<div id="list-item">3</div>
<div id="list-item">4</div>
<div id="list-item">5</div>
<div id="list-item">6</div>
</div>
</div>
</div>
</body>
</html>
Related: Why is a flex-child limited to parent size?
As a side note, if you remove overflow:hidden
from the container the result will be the same for both cases:
html {
height: 100%;
background:#fff;
}
body {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
background:red;
}
#header {
background-color: brown;
flex: 0 0 100px;
}
#grid-container {
flex: 1 1 auto;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
border:5px solid green;
}
#grid-item {
grid-column: 1/2;
grid-row: 1/2;
overflow: auto; /*will do nothing*/
border:5px solid blue;
}
#list {
/* overflow: auto; not needed*/
border:5px solid yellow;
}
#list-item {
font-size: 140px;
}
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
</head>
<body>
<div id="header"></div>
<div id="grid-container">
<div id="grid-item">
<div id="list">
<div id="list-item">1</div>
<div id="list-item">2</div>
<div id="list-item">3</div>
<div id="list-item">4</div>
<div id="list-item">5</div>
<div id="list-item">6</div>
</div>
</div>
</div>
</body>
</html>
This is due to The Automatic Minimum Size of Flex Items that will prevent the shrink effect.
Upvotes: 2