问题
If we start with this setup of HTML elements:
...and then we make use of CSS flexbox and apply the flex-grow
property to the "body" element, we get this:
Which is fantastic that it's behaviour that can be done purely in CSS without the need for any JavaScript.
However, say we want to have a fixed height for the parent container element and that the child elements (i.e. header, body and footer), should not overflow the parent.
Say the header and footer element content are fixed, but the body content is dynamic (server-side or client-side, it doesn't matter) and that we want the body element to have vertical scrollbars when the content gets too big, like so:
However, I can't find a way to achieve that behaviour purely in CSS (i.e. without the use of JavaScript) and without specifying fixed heights for all the child elements (undesirable).
Simply using the flex-grow
property with a fixed height on the parent, results in this (when the body content gets too big):
Is there a way to do it in pure CSS?
If not, do we think it might be worth extending the flexbox standard to encapsulate this kind of behaviour?
Edit 1
So my use-case is similar to what I posted, but different enough to have hidden the problem and hence raised a few eyebrows as to why I'm even having problems in the first place.
Expanding on LGSon's answer, this is my use-case:
html, body {
margin: 0;
}
body {
display: flex; /* IE 11/10 min-height bug fix - or an extra wrapper in the markup */
}
.wrapper {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
}
.body {
flex: 1;
}
.content {
overflow: auto;
}
/* below CSS is just for the extra styling */
.wrapper {
height: calc(100vh - 44px); /* 2*2px border + 2*10px margin */
width: calc(100% - 44px); /* + 2*10px padding = 44px */
border: 2px dashed black;
margin: 10px;
padding: 10px;
}
.wrapper > div {
padding: 10px;
}
.header {
border: 2px solid blue;
margin-bottom: 10px;
}
.body {
border: 2px solid green;
}
.footer {
border: 2px solid red;
margin-top: 10px;
}
<div class="wrapper">
<div class="header">
Header<br>
</div>
<div class="body">
<h1>
Hello world!
</h1>
<div class="content">
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
</div>
</div>
<div class="footer">
Footer<br>
</div>
</div>
So I actually had another level in the hierarchy and I had the overflow
property one level too deep.
To me it seems logical to have the overflow
where I had it, but building from your answers/examples, even from my use-case, moving it up a level, makes it work (counter-intuitively, in my opinion).
I can half understand why it works, but I would have thought the scroll bar would span the whole body element and not just the content part.
Sorry about the unintentional misleading.
Thanks everyone.
Edit 2
I'll reward the first person to alter their answer (or create a new one), that incorporates my clarification (in the first edit), with the correct answer.
回答1:
This sample using flexbox
does what you asked, with no fixed height on the children.
Fully dynamic .header
and .footer
, and a .body
that will scroll when needed, so it all stays within its parent, the .wrapper
.
Note, regarding the scroll, you give the element you want to have the scroll an overflow, not the element that might cause the overflow.
html, body {
margin: 0;
}
body {
display: flex; /* IE 11/10 min-height bug fix - or an extra wrapper in the markup */
}
.wrapper {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
}
.body {
flex: 1;
overflow: auto;
}
/* below CSS is just for the extra styling */
.wrapper {
height: calc(100vh - 44px); /* 2*2px border + 2*10px margin */
width: calc(100% - 44px); /* + 2*10px padding = 44px */
border: 2px dashed black;
margin: 10px;
padding: 10px;
}
.wrapper > div {
padding: 10px;
}
.header {
border: 2px solid blue;
margin-bottom: 10px;
}
.body {
border: 2px solid green;
}
.footer {
border: 2px solid red;
margin-top: 10px;
}
<div class="wrapper">
<div class="header">
Header<br>
</div>
<div class="body">
<h1>
Hello world!
</h1>
<div class="content">
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
</div>
</div>
<div class="footer">
Footer<br>
</div>
</div>
When you say the whole body element, if you instead mean the actual html body
, not the element with the .body
class, then use a min-height
on the .wrapper
and remove the overflow from the .body
.
You could set the overflow to the html body
element, though it's not needed as it scrolls by default
html, body {
margin: 0;
}
body {
display: flex; /* IE 11/10 min-height bug fix - or an extra wrapper in the markup */
}
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
}
.body {
flex: 1;
}
/* below CSS is just for the extra styling */
.wrapper {
min-height: calc(100vh - 44px); /* 2*2px border + 2*10px margin */
width: calc(100% - 44px); /* + 2*10px padding = 44px */
border: 2px dashed black;
margin: 10px;
padding: 10px;
}
.wrapper > div {
padding: 10px;
}
.header {
border: 2px solid blue;
margin-bottom: 10px;
}
.body {
border: 2px solid green;
}
.footer {
border: 2px solid red;
margin-top: 10px;
}
<div class="wrapper">
<div class="header">
Header<br>
</div>
<div class="body">
<h1>
Hello world!
</h1>
<div class="content">
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
Content<br> Content<br>
</div>
</div>
<div class="footer">
Footer<br>
</div>
</div>
回答2:
Here's a version with minimal CSS, which allows for your requirements, I think.
* { margin: 0; padding: 0; }
html,body {
max-height: 100%;
height: 100%;
}
#header {
border: 2px solid blue;
color: blue;
height: 4em;
margin-bottom: .5em;
}
#content {
border: 2px solid green;
color: green;
height: calc(100vh - 10em);
margin-bottom: .5em;
overflow-y: scroll;
}
#footer {
border: 2px solid red;
color: red;
height: 4em;
}
<body>
<div id="header">This is the header</div>
<div id="content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
<p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. </p>
<p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. </p>
<p>Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p>
<p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p>
<p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>
<p>Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. </p>
<p>Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. </p>
<p>Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. </p>
<p>Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. </p>
</div>
<div id="footer">This is the footer</div>
</body>
回答3:
Flexbox does just that.. Could it be you forgot to remove the default margin on the body?
.wrapper {
height: 100vh;
display: flex;
flex-direction: column;
}
body {
margin: 0;
}
header, footer {
background: grey;
flex-basis: 50px;
}
section.grow {
flex-grow: 1;
}
<div class="wrapper">
<header></header>
<section class="grow"></section>
<footer></footer>
</div>
来源:https://stackoverflow.com/questions/41443909/how-to-automatically-stretch-and-yet-constraint-html-child-element-within-parent