Reputation: 43402
In the following situation, why is the height of <header>
reduced? As far as I can see, <header>
should retain the height declared in by flex-basis
and <div class="content-wrapper">
should take up the remaining space. This does work until it contains content that is taller than the space available to it. In this situation, <header>
partially collapses.
main {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
}
header {
flex-basis: 50px;
background: red;
}
.content-wrapper {
background: blue;
flex: 2;
overflow-y: auto;
}
.content {
height: 1000px;
background: green;
}
<main>
<header></header>
<div class="content-wrapper">
<div class="content"></div>
</div>
</main>
If you run the snippet full-screen and change the height, the header height changes relative to the screen-height. I would expect it to remain fixed at 50px.
Upvotes: 6
Views: 3461
Reputation: 7489
Apologies for necro posting but Google led me here for my issue of flex-basis being ignored, it was for a different reasons than the OP but this might help someone out there. I was trying to make images arrange side by side with equal size but some unwrappable text forced one box to be larger than the flex-basis I set, causing the layout to break.
In my case the fix was to add overflow-wrap: anywhere
so the text became wrappable, and the layout engine could force the flex item to be 25% of the parent's width.
.container {
max-width: 20em;
margin: 1em auto;
border: 2px solid black;
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 1 25%;
display: block;
height: 4em;
margin: 0;
/* This will fix the 25% width problem: overflow-wrap: anywhere; */
}
.item.a { background-color: red; }
.item.b { background-color: green; }
.item.c { background-color: blue; }
.item.d { background-color: goldenrod; }
<div class="container">
<div class="item a">
<span>One fish two fish red fish blue fish.</span>
</div>
<div class="item b">
<span>One fish two fish red fish blue fish.</span>
</div>
<div class="item c">
<span>One fish twofishredfishblue fish.</span>
</div>
<div class="item d">
<span>One fish two fish red fish blue fish.</span>
</div>
</div>
<p>The 4 children have been told to be 25% the width of the flex container, but are not because one has unwrappable text content causing it to lay out too wide.</p>
<p>Uncommenting the overflow-wrap style to set it to 'anywhere' will allow that item to wrap its contents and obey the 25% rule.</p>
I was actually layout out figure
elements with a figcaption
and a gap
rule in between the items, which means the simple flex-basis: 25%
doesn't work, so for bonus points here's use of calc()
to set the flex-basis
of each item, though admittedly it's a bit of a hack because it involves knowing the number of children and the gap size.
.container {
max-width: 20em;
margin: 1em auto;
border: 2px solid black;
display: flex;
flex-wrap: wrap;
gap: 10px; /* see flex-basis later */
}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: calc(25% - 3 * 10px);
display: block;
margin: 0;
overflow-wrap: anywhere;
}
.item.a { background-color: red; }
.item.b { background-color: green; }
.item.c { background-color: blue; }
.item.d { background-color: goldenrod; }
<div class="container">
<div class="item a">
<span>One fish two fish red fish blue fish.</span>
</div>
<div class="item b">
<span>One fish two fish red fish blue fish.</span>
</div>
<div class="item c">
<span>One fish twofishredfishblue fish.</span>
</div>
<div class="item d">
<span>One fish two fish red fish blue fish.</span>
</div>
</div>
<p>Since we know there are 3 gaps of 10px each, we can set the flex-basis to be `calc(25% - 3 * 10px)` which makes each item a little less than 25% the width of the parent to fit all 4 on one row nicely without wrapping.</p>
Upvotes: 0
Reputation: 13037
@Eric Martinez' comment is correct. To keep elements from shrinking, set flex-shrink
to 0 instead.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
main {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
}
header {
height: 50px;
flex-shrink: 0;
background: red;
}
.content-wrapper {
background: blue;
flex: 2;
overflow-y: auto;
}
.content {
height: 1000px;
background: green;
}
<main>
<header></header>
<div class="content-wrapper">
<div class="content"></div>
</div>
</main>
Upvotes: 7