Nathan Osman
Nathan Osman

Reputation: 73165

Why can't this textarea assume the full height of its parent in Chrome?

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

Answers (4)

gsnedders
gsnedders

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

Michael Benjamin
Michael Benjamin

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

Abe
Abe

Reputation: 1415

Try to change this:

.expand {
  flex-grow: 1;
}

to

.expand {
  flex: 1;
}

Upvotes: 0

kyun
kyun

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

Related Questions