Reputation: 73165
Consider the following page, which displays a line of text with a <textarea>
underneath it.
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
.outer {
background-color: #eee;
display: flex;
flex-direction: column;
height: 100%;
padding: 10px;
}
.expand {
flex-grow: 1;
}
textarea {
height: 100%;
width: 100%;
}
<div class="outer">
<p>
Nice little wall of text.
</p>
<div class="expand">
<textarea></textarea>
</div>
</div>
The intended behavior is to have the textarea occupy the remaining height of the page underneath the line of text. Using flexbox, I can make the .expand
element occupy the remaining height of the page. However, despite having height: 100%;
set on the textarea it refuses to occupy the full height of its parent.
Why isn't this working and how can I make the textarea fill its parent?
Upvotes: 4
Views: 4424
Reputation: 5692
CSS has a concept of block width/height as "definite" or "indefinite"; essentially .
Percentages need to have a definite length to resolve against, and Chrome doesn't consider flex items definite
in this case, contrary to the current spec.
There are two easy fixes here: either set flex-basis
to a <length>
(when it's the only flex item that can grow, it doesn't actually matter what length this is, it just can't be the other values of none
or auto
, so flex-basis: 0
works fine), or give it a definite height (and it similarly doesn't matter, so height: 0
works fine).
Alternatively, you can make .expand
itself a flexbox with the textarea
child expanding to fill the parent as one of the other answers suggests.
Upvotes: 0
Reputation: 370993
Your .expand
div actually does work as intended. It occupies the remaining height of the parent.
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
.outer {
background-color: #eee;
display: flex;
flex-direction: column;
height: 100%;
padding: 10px;
border: 2px dashed red;
}
.expand {
flex-grow: 1;
border: 2px dashed blue;
}
textarea {
height: 100%;
width: 100%;
}
<div class="outer">
<p>Nice little wall of text.</p>
<div class="expand">
<textarea></textarea>
</div>
</div>
However, the textarea
is a child of .expand
, and you've set it to height: 100%
.
Since percentage heights are normally based on the specified height of the parent, and there is no height
defined on .expand
, the textarea
height computes to auto
(more complete explanations here and here).
The simplest and most efficient solution is to get rid of the percentage height on the textarea
and give the parent display: flex
, which automatically applies align-items: stretch
to the child.
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
.outer {
background-color: #eee;
display: flex;
flex-direction: column;
height: 100%;
padding: 10px;
border: 2px dashed red;
}
.expand {
flex-grow: 1;
border: 2px dashed blue;
display: flex;
}
textarea {
width: 100%;
}
<div class="outer">
<p>
Nice little wall of text.
</p>
<div class="expand">
<textarea></textarea>
</div>
</div>
Upvotes: 5
Reputation: 10254
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
.outer {
background-color: #eee;
display: flex;
flex-direction: column;
height: 100%;
padding: 10px;
}
.expand {
flex: 1;
}
textarea {
height: 100%;
width: 100%;
}
<div class="outer">
<p>
Nice little wall of text.
</p>
<div class="expand">
<textarea></textarea>
</div>
</div>
.expand {
flex: 1;
}
Upvotes: 1