position:fixedでヘッダー固定時に重なる問題をCSSで解決する方法
2023/02/20
最近のブログやWordPressのテーマには、ヘッダーを固定するタイプのものもあります。
ヘッダーを固定する時に用いられるCSSと言えばposition:fixed
です。
例えば、ヘッダーメニューを画面上部に固定することで、ページのどの位置からでもサイト内の他のページへアクセスしやすくなります。
ブログによっては、追尾型の広告エリアとして使用している場合もあるでしょう。
このように何かと使う機会が多いposition:fixed
ですが、以下のようなアクシデントに見舞われていないでしょうか。
ヘッダーにはposition:fixed
とtop:0
を指定しており、画面上に固定されています。
上図ではスクロールバーがページの最上部にある状態ですが、本来あるべき1行目から3行目までが表示されていませんね。
実は表示されていないのではなく、画面上に固定されているヘッダーに覆い隠されてしまっているのです。
下図のように、ヘッダーを透明化してみるとわかりやすいでしょう。
ヘッダー下にきちんと1行目から3行目までが記述されていることを確認できます。
とは言え、コンテンツは見えなければ(利用できなければ)意味がありません。
今回はposition:fixed
で固定した要素と、その下の要素が重なる問題の原因と解決策について、解説したいと思います。
もくじ
1.固定したヘッダーが隣の要素の上に重なる原因とは
固定された要素によって下の要素が見えなくなる原因はpositin:fixed
の性質にあります。
というのもpositin:fixed
を指定された要素は、画面を基準にした絶対的な位置に配置され、元々の位置・領域は詰められるからです。
例えば、以下のHTMLを確認してください。
1 2 |
<div class="sample_01"></div> <div class="sample_02"></div> |
CSSは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 |
.sample_01 { width: 100px; height: 100px; background: tomato; } .sample_02 { width: 200px; height: 200px; background: steelblue; } |
最初の.sample_01
には100px
四方のtomato
色を、次の.sample_02
には200px
四方のsteelblue
色を施しています。
まずはposition:fixed
を適用しないパターンをご覧ください。
通常、このようにHTMLで記述されている順番に並べられます。
では、.sample_01
にposition:fixed
を適用し、画面右端に固定(right:0
)してみるとどうなるでしょうか。
すると、本来.sample_01があった位置に.sample_02が移動していることがわかります。
このように画面左上に固定されるのと引き換えに、元々の.sample_01
の位置と領域は詰めて表示される仕様になっています。
固定されたヘッダーによって、下のコンテンツが隠れてしまう問題も同様です。
最初の例のHTMLを見てみましょう。
1 2 3 4 5 6 7 8 |
<header> <h1>Header</h1> </header> <main> <p>1行目</p> <p>2行目</p> <!-- 以下略 --> </main> |
通常、この記述順なら、下図のようにheader→mainの位置関係で表示されるはずです。
そして、header
にposition:fixed
を指定した時の結果が下図です。
本来headerがあった領域に、すぐ後ろのmainが移動しているために、固定ヘッダーと重なり合ってしまっていたわけです。
2.CSSでヘッダーが重ならないようにする3つの解決策
position:fixedを指定したヘッダーと、すぐ後ろの要素が重なる問題を解決する方法として、以下の3点を挙げることができます。
- すぐ後ろの要素にヘッダーと同じ高さの余白(margin)を入れる
- bodyにヘッダーと同じ高さの余白(padding)を入れる
- position:stickyに変更する
どのパターンでも対応できますが「3」の方法はIEで対応していないので注意してください。
それでは、一つずつ解説していきます。
2-1.すぐ後ろの要素にヘッダーと同じ高さの余白(margin)を入れる
ヘッダーのすぐ後ろの要素にヘッダーと同じ高さのmargin-top
を指定することで、固定時の重なりを防ぐことができます。
例えば、今回の例で言えば、header
のすぐ後ろにあるmain
のmargin-top
を調整してあげます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
header { height: 80px; /* (※)ヘッダーの高さを確認 */ position: fixed; top: 0; left: 0; right: 0; background: tomato; } main { margin-top: 80px; /* (※)の高さに合わせる */ padding-left: 10px; background: steelblue; } |
上記のように、headerのheightの値に合わせるか、それよりも大きい値を指定しましょう。
結果は以下の通りです。
1行目から3行目までがヘッダーに重ならずに、きちんと表示されています。
2-2.bodyにヘッダーと同じ高さの余白(padding)を入れる
あるいは、同じ高さの余白をbody
のpadding-top
に指定しても良いです。
1 2 3 4 5 6 7 8 9 10 11 12 |
body { padding-top: 80px; } header { height: 80px; position: fixed; top: 0; left: 0; right: 0; background: tomato; } |
padding-top
の場合にもheader
のheight
を確認し、同じかそれ以上の値を指定してあげてください。
2-3.position:stickyに変更する
最も手軽なのはheader
のposition
をsticky
に変更する方法です。
1 2 3 4 5 6 7 8 |
header { height: 80px; position: sticky; top: 0; left: 0; right: 0; background: tomato; } |
stickyは要素を元の位置に配置しながら、画面上で指定の位置に達した時のみ固定する値です。
さらに元の領域を保ったまま固定されるため、ヘッダーとすぐ後ろのコンテンツが重なって利用できなくなる心配もありません(重なってもスクロールすれば利用できます)。
ただし、IEはstickyに対応していないため注意してください。
※各ブラウザのsticky対応状況:CSS position:sticky | Can I use…
3.まとめ
今回はヘッダーにposition:fixed
を使用する際に「重なる」問題について、その原因と解決策について説明しました。
position:fixed
を指定すると、元の位置・領域が詰められる- すぐ後ろの要素の
margin-top
やbody
のpadding-top
に、ヘッダーの高さよりも大きい値を指定することで重ならずに済む position:sticky
に変更するのが最も手っ取り早いが、一部のブラウザで対応されていない