Webサイトを訪問した際、一番初めに目に入るものとはなんでしょうか。
目を惹くメインビジュアル?仰々しいキャッチコピー?
リッチなサイトならばローディング画面?
サイトの構成によってその答えも異なりますが、ほとんどの場合、
そうした注目ポイントに付随するように ヘッダー の存在があるのではないでしょうか。
この文章を読んでいる頃ならまだ、最近新しくなったQiitaロゴを有した黄緑色のヘッダーが画面上部に拝めるのではないかと思います。スマホの方は少しだけ上にスクロール。
サイト共通のヘッダーとは、ある種サイトの名刺のようなものであり、サイトの回遊を助けるナビゲーターであり、常にユーザーに寄り添うような(最近は追従するヘッダーも多いですね)、甘くてクリーミーな特別な存在(パーツ)なのです。
Webサイトを構築するうえで、(この言葉は苦手なのですが) 必須 ともいえるヘッダー。
そんなヘッダーを作るときにHTMLをどう書くかについて考えます。
サンプルケース
サンプルとして特に装り気もない 一般的な ヘッダーをつくります。
一般的ってなんじゃいという話なのですが、
- タイトル兼トップに戻るリンクゾーン
- ナビゲーションリストゾーン
- ハンバーガーメニューボタン
最低限これらさえあればヘッダーとして名乗りを上げることはできるでしょう。
クラスに関してはわかりやすいようBEMライクに書くとして、ひとまずアウトラインを作成します。
<header class="header">
<!-- タイトル兼トップに戻るリンクゾーン -->
<h1 class="header_title">
<a href="/">サイトタイトル</a>
</h1>
<!-- ナビゲーションリストゾーン -->
<nav class="header_nav">
<ul class="header_navList">
<li><a href="#section01">項目01</a></li>
<li><a href="#section02">項目02</a></li>
<li><a href="#section03">項目03</a></li>
</ul>
</nav>
<!-- ハンバーガーメニューボタン -->
<button type="button" class="header_btn">三</button>
</header>
う〜んセマンティック。見事にヘッダーの材料が揃っていますね。
(ハンバーガーメニューに関してはコードが長くなるため今回は省略します)
とはいえCSSを当てていない状態ではヘッダーもどきにすらなりきれていません。
早速調理を開始したいところなのですが、このHTMLには欠けているものがあります。
<div>
がひとつもないのです。
<header>は<div>の代わりではない
これは <header>
に限らず、HTML5においてよく言われることですね。
<section>
や <nav>
のようにHTMLのアウトラインを生成するわけではない……つまりセクショニングコンテンツではないとされているため、 <header>
で囲む意味としては「ここがヘッダーですよ〜」という目印程度のものと考えられます(それが重要ではあるのですが)。
ただ、今のコードではその目印である <header class="header">
しか、色をつけたり引き伸ばしたりする対象がありません。
.header {
display: flex;
align-items: center;
background: #ccc;
width: 100%;
height: 60px;
/* etc... */
}
こんな感じでほとんどのCSSが一点に集中せざるを得なくなります。
ここから「背景は画面いっぱいに、だけど内部の最大幅を1000pxに収めたい」とかしようとすると、えっこれ無理では?……となって、結局 <div>
でcontainerやinnerを書くことになります。
そんなことなら最初からこうしましょう。
<header class="header">
<div class="header_container">
<div class="header_inner">
<!-- 中身は省略 -->
</div><!-- /.header_inner -->
</div><!-- /.header_container -->
</header>
.header {
/* display: flex;
align-items: center;
background: #ccc;
width: 100%;
height: 60px; */
}
.header_container {
background: #ccc;
width: 100%;
height: 60px;
}
.header_inner {
display: flex;
align-items: center;
margin: auto;
max-width: 1000px;
}
ネストは増えましたが、こんな感じに分割した方が後々の修正もしやすそうですね。
<header>
にいたってはCSSが空っぽになってしまいましたが、「<header>は<div>の代わりではない」ので、<header>を修飾するためには別の <div> が必要だった と考えるとよさげです。
そもそも、 <header class="header">
という書き方も、今となってはもにょります。
まるでHTML5すら知らなかった幼き日に書いた <div class="header">
を 置換しただけ のようで……。
(BEMのルール的には仕方なさそうなのですが)
<section>も<div>の代わりにしない方がいい
先ほどの修正によって、 <header>
に何もCSSが当たらなくなったように、個人的にはセクショニングコンテンツである <section>
にも直接CSSをあらかじめ当てておくのはやめた方がいいのではないかと考えています。
通常の場合は特に問題ないのですが、例えば先ほどのヘッダーがスクロールに合わせて追従する……。
いわゆる固定ヘッダーになった場合、position: fixed;
を付けることでヘッダーを浮かせて固定します。
.header {
position: fixed;
}
浮いたヘッダーに後に続くメインコンテンツが隠れないよう、ヘッダーの高さ分(今回は 60px
)ずらす必要があるのですが、もし固定ヘッダーに各セクションへのアンカーリンク <a href="#~~~">
がある場合、アンカーの到着する位置も同じだけズラす必要があります。
この問題を解消するCSSが以下なのですが、
section {
margin-top: -60px;
padding-top: 60px;
}
もしこれを background
と併用してしまうと、padding-top
の分だけ伸びた背景が margin-top
のネガティブマージン分だけ上にズレることになるため、本来の位置よりもヘッダーの高さ分上にズレて見える <section>
が爆誕します(そもそも margin
や padding
を当てている場合もそれらを上書きしてしまいますね)。
これを防ぐためには先ほどのヘッダーのように、内に身代わりの <div>
をかますことが大事です。
<section id="#section01">
<div class="section_container">
<div class="section_inner">
<!-- 中身は省略 -->
</div><!-- /.section_inner -->
</div><!-- /.section_container -->
</section>
section {
margin-top: -60px;
padding-top: 60px;
}
.section_container {
background: #000000;
/* ... */
}
他にも考えることは色々とあるのですが、HTMLをシンプルにしすぎるのもほどほどにした方がよさそうです。
おまけ
実ははじめに見ていただいたQiitaのヘッダーのガワ部分も、
<div class="st-HeaderContainer">
とガッツリ <div>
だったりします。
(グローバルフッターは <footer>
だったので、なにか意図があるのかないのか分かりませんが)
あらためて、タグの定義された意図を再解釈する必要があると感じる年末なのでした。