"height: 100%" の要素が画面の高さ100%にならない場合の対応方法

ページ内の特定の要素を「ブラウザ画面の高さ100%」で表示させたい場合を考えます。
（各要素は通常フローで配置されているものとします）

# 期待通りの表示にならないCSS

以下のようなCSS指定が思いつきますが、この場合 `.fullheight` 要素はブラウザ画面の高さ100%にはなりません。

~~~css:CSS

body {
  margin: 0;
}

.fullheight {
  height: 100%;
  background: #bbddff;
}

~~~

~~~html:HTML

<body>
  <div class="fullheight">
    高さ100%で表示したい要素
  </div>
</body>

~~~

<p class="codepen" data-height="300" data-theme-id="18225" data-default-tab="result" data-user="shouchida" data-slug-hash="qBaRbrO" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qiita_205fed63b886681661bd_01">
  <span>See the Pen <a href="https://codepen.io/shouchida/pen/qBaRbrO">
  qiita_205fed63b886681661bd_01</a> by Sho Uchida (<a href="https://codepen.io/shouchida">@shouchida</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# 期待通りの表示となるCSS

以下のように、html要素とbody要素に `height: 100%;` を指定すると、期待通りの表示結果となります。

~~~css:CSS

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

.fullheight {
  height: 100%;
  background: #bbddff;
}

~~~

~~~html:HTML

<body>
  <div class="fullheight">
    高さ100%で表示したい要素
  </div>
</body>

~~~

<p class="codepen" data-height="300" data-theme-id="18225" data-default-tab="result" data-user="shouchida" data-slug-hash="LYRxGyG" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qiita_205fed63b886681661bd_02">
  <span>See the Pen <a href="https://codepen.io/shouchida/pen/LYRxGyG">
  qiita_205fed63b886681661bd_02</a> by Sho Uchida (<a href="https://codepen.io/shouchida">@shouchida</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# height に相対値（%）が指定された場合の高さの算出

このような height プロパティの振る舞いは、もちろんCSSの仕様として決められているものです。

[height - CSS | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/height)

ある要素の height に相対値（%）が指定された場合、その高さは**包含ブロックの高さに対して**計算されます。
その要素が通常フローで配置されており、かつ**包含ブロックの高さが明示されていない**場合、要素の高さは **`auto`** として計算されます。

なお、包含ブロックについては下記の記事が詳しいです。

[包含ブロック｜前提知識｜CSS2.1](https://w3g.jp/css/guide/contining_block)

最初の例では、`.fullheight` の包含ブロックである `<body>` に height が明示されていなかったため、`height: auto;` と同様の結果となっていました。

## 包含ブロックに height が明示されている場合

`.fullheight` の包含ブロックとなる `.wrapper` を新たに設置し、`height: 500px;` を指定してみます。
さらに `.fullheight` に対しては `height: 80%;` と指定しましょう。

この場合、`.fullheight` 要素の高さは**「500px の 80% ＝ 400px」**として計算されます。

~~~css:CSS

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

.wrapper {
  height: 500px;
  background: #99bbee;
}

.fullheight {
  height: 80%;
  background: #bbddff;
}

~~~

~~~html:HTML

<body>
  <div class="wrapper">
    <div class="fullheight">
      高さ80%で表示したい要素
    </div>
  </div>
</body>

~~~

<p class="codepen" data-height="600" data-theme-id="18225" data-default-tab="result" data-user="shouchida" data-slug-hash="GRjromE" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qiita_205fed63b886681661bd_03">
  <span>See the Pen <a href="https://codepen.io/shouchida/pen/GRjromE">
  qiita_205fed63b886681661bd_03</a> by Sho Uchida (<a href="https://codepen.io/shouchida">@shouchida</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

---

では、上記の状態から、さらに要素をひとつ増やす（`.inner`）とどのような表示になるでしょうか？

~~~css:CSS

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

.wrapper {
  height: 500px;
  background: #99bbee;
}

.inner {
  /* height指定無し */
}

.fullheight {
  height: 100%;
  background: #bbddff;
}

~~~

~~~html:HTML

<body>
  <div class="wrapper">
    <div class="inner">
      <div class="fullheight">
        高さ80%で表示したい要素
      </div>
    </div>
  </div>
</body>

~~~

<p class="codepen" data-height="600" data-theme-id="18225" data-default-tab="result" data-user="shouchida" data-slug-hash="MWjJKmx" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qiita_205fed63b886681661bd_04">
  <span>See the Pen <a href="https://codepen.io/shouchida/pen/MWjJKmx">
  qiita_205fed63b886681661bd_04</a> by Sho Uchida (<a href="https://codepen.io/shouchida">@shouchida</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

先ほどと同じ結果になりそうな気もしますが、`.fullheight` の包含ブロックとなる **`.inner` に height が明示されていない**ため、`.fullheight` の高さは `auto` として計算されます。

## まとめ

通常フローで配置された `height: 100%;` の要素を「ブラウザ画面の高さ100%」で表示させたい場合、ブロックボックスを形成する祖先要素それぞれに対しても `height: 100%;` を指定する必要があります。