问题
So I was trying to get a header and some content to fit into the screen by having a div #main
with height: 100%
as a flexbox, just like this:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</body>
</html>
So now if #content
overflows the height of #main
, #content
's scrollbar will take over, and the header stays visible. Works like a charm so far.
My problem is now that I need to nest another combination of header and screen fitting content into the outer content, which I tried to solve with another nested flexbox:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
</body>
</html>
So basically I want both headers to stay up top now, and have only the inner content box scroll once it overflows. But when it does, the content stretches beyond (?!) #main
's height, triggering the browser pages's scrollbar instead of its own one. I suppose the problem may be caused by the outer content box, whose height is only defined by the outer flexbox.
I already had tried a solution where the headers would have absolute positions, but this doesn't quite work out for what I need it. Flexboxes would be just perfect if it wasn't for this problem.
Can anyone help me fix this?
回答1:
What you ask for is already happening in Chrome. Which makes me think you're developing with FF.
As a side-note, I believe that's a mistake, simply because you're developing for less than 15% of your target audience to only fix browser differences for another 65% of your audience. Luckily for you, they both keep tight to standards and differences are quite few these days.
Another reason why you might prefer Chrome over FF as a development tool is that FF has consistently been 6 months behind regarding dev tools for at least 4 years now. Don't get me wrong, I'm not a big Chrome fan and I fully welcome using FF as browsing device of choice. But, as a development tool, it's just not the best available. And they're both free.
Back to your question, adding overflow-y:auto
to .flexbox
seems to fix it in FF, too:
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
overflow-y: auto;
}
.header {
flex: 0 1 auto;
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
}
.scrollable {
overflow-y: scroll;
}
<html>
<body>
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
</body>
</html>
Note: of course, you'd need to run your code through a prefixer for a wider browser coverage. Mind the "filter" box below it. Set to > 0%
for maximum cross-browser compatibility.
回答2:
This issue affects not only Firefox, also Edge and IE11 overflow the parent.
It's caused by the fact that flex item's min-height
* defaults to auto
, and as such can't be smaller than its content. (Chrome tries to fix this by itself, hence it works on it, though, IMHO, it shouldn't)
* Very well explained here: The Implied Minimum Size of Flex Items
The affected element is the <div class="content flexbox">
, which will overflow because if this.
The solution is to change its min-height
to 0
, and with that will allow it to shrink past content.
For IE11, see notes/sample below.
Stack snippet
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
min-height: 0; /* Firefox, Edge */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
As IE11 being a lot buggier, the above isn't enough, and there is 2 ways to fix it:
Using flex: 1 1 0%
, which will make IE11 believe there is no content, hence will only grow as big as the available space in its parent.
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 0%; /* IE11, changed from "auto" to "0%" */
border: 2px solid #00aa00;
min-height: 0; /* Firefox, Edge */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
Using overflow: hidden
(see note at the end)
#main {
height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
display: flex;
flex-direction: column;
}
.header {
/*flex: 0 1 auto; default, so not needed */
border: 2px solid #aa0000;
}
.content {
flex: 1 1 auto;
border: 2px solid #00aa00;
/*min-height: 0; not needed, as overflow has same effect */
overflow: hidden; /* Firefox, Edge, IE11 */
}
.scrollable {
overflow-y: scroll;
}
<div id="main" class="flexbox">
<div class="header">
HEADER
</div>
<div class="content flexbox">
<div class="header">
HEADER
</div>
<div class="content scrollable">
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>CONTENT<br>CONTENT<br>
</div>
</div>
</div>
Note, using overflow
with a value other than visible
(its default), will have the same effect as min-height
, where hidden
is considered more safe than auto
, avoiding future change in behavior to render a scrollbar.
回答3:
You can fix this by using two height: 0
on the main box and the content box.
html,
body {
height: 100%;
}
.topheader {
background: orange;
width: 90%;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background: red;
}
.subcontainer {
display: flex;
flex-direction: column;
flex: 1 1 auto;
height: 0;
width: 90%;
background: blue;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0;
opacity: 0.5;
}
#container footer {
background-color: gray;
}
<section id="container">
<div class="topheader">
Top Header
</div>
<div class="subcontainer">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />
With a lot of lines.
<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines.<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines
<br />
<br />
This is the content that
<br />
With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</div>
</section>
来源:https://stackoverflow.com/questions/48389994/nesting-flexbox-inside-flexbox-overflow-how-to-fix-this