次図のようなレイアウトで、スクロールが発生するほど大きな要素を内部に持っていてもヘッダーとフッターを画面内に置き、コンテンツだけをスクロールできるようにする方法を紹介します。
具体的には次のようにできます。
<html lang="ja"> <head> <title>demo</title> <meta charset="utf-8"> <style> /* grid を使ってヘッダーとフッターはそれぞれに合った高さにし */ /* コンテンツは残りの高さ全てを使うようにする */ .page { height: 100%; width: 100%; display: grid; grid-template-rows: fit-content(100%) 1fr fit-content(100%); } /* 内部要素が大きい場合はスクロールが発生するようにする */ .page > .content { overflow: auto; } /*スクロールするコンテンツの中身。*/ /*スクロールを発生させるために高さと幅を大きくとり*/ /*スクロールしていることを分かりやすくするためにグラデーションをつける*/ .big-item { height: 3000px; width: 3000px; background: -moz-linear-gradient(135deg, #000, #fff); background: -ms-linear-gradient(135deg, #000, #fff); background: -o-linear-gradient(135deg, #000, #fff); background: -webkit-linear-gradient(135deg, #000, #fff); } /* デモ用にヘッダー、フッター、コンテンツの境界を分かりやすくするためのデザイン */ .page { gap: 1em; } header, footer { padding: 1em; background: #aaa; display: flex; justify-content: center; align-items: center; } </style> </head> <body> <div class="page"> <header> ここはヘッダーです </header> <div class="content"> <div class="big-item"></div> </div> <footer> ここはフッターです </footer> </div> </body> </html>
何をやっているかというと次の通りです。
次のコードのようにグリッドデザインの fit-content と fr を組み合わせることによって、内部要素にあった大きさにしたいヘッダーとフッターと親要素の余った部分全体にしたいコンテンツそれぞれの大きさを決めています。
/* @see https://developer.mozilla.org/ja/docs/Web/CSS/grid-template-rows */ /* @see https://developer.mozilla.org/ja/docs/Web/CSS/fit-content_function */ .page { display: grid; grid-template-rows: fit-content(100%) 1fr fit-content(100%); }
加えてdisplay:grid
である.page
要素の幅と高さの指定と内部要素である.content
のoverflow:auto
によって、.content
の中身が大きい時だけ.content
にスクロールが起きるようにしています。もしこの指定がないと状態で内部要素が大きい場合、.page
が大きくなりヘッダーとフッターが隠れてしまいます。
.page { height: 100%; width: 100%; } .page > .content { overflow: auto; }
このレイアウトはユーザーが巨大なコンテンツをスクロールしながら、ヘッダーやフッターでそのコンテンツを操作する、といったような画面で便利です。またグリッドを使わずに似たレイアウトを作る場合ではよくヘッダーにposition:fixed
、コンテンツにtop: $ヘッダーの高さ
の様なものを使っていましたが、こちらのやり方ではヘッダーの下に重要な要素がもぐりこむ不具合が起こりやすかったです(ヘッダーの高さが想定外の長さになるなどして起きます)。グリッドを使う方法ではz-index
が統一され、そういった問題が起きにくくもなります。