こんにちは。Web制作フリーランスのホリエです。
皆さんは、ページをコーディングするときに一番最初に手を付けるのはどこでしょうか?ヘッダーが一番先頭にあるので、ヘッダーからという方も多いのではないでしょうか。
でも、ヘッダーはレイアウト的に複雑な場合が多く、意外と苦戦することも多いです。はりきってコーディングしようとしたのに、いきなり出鼻をくじかれることもコーダーあるあるかと思います。
逆に言うと、ヘッダーがスムーズにコーディングできたら、幸先良いスタートダッシュが切れそうですよね。
というわけで、今回は、ヘッダーのコーディングをしていきます。Progateからスタートした初学者が最初にぶつかる関門としてヘッダーの実装を挙げる方が多いと思いますので、ここでしっかり基礎を理解していきましょう!
今回実装するヘッダーは下記です。
- 左端に会社ロゴ、右端にハンバーガーボタンが横並び
- ヘッダーの最大幅は1000pxで左右中央寄せ
- レスポンシブ時の左右の余白はブラウザ幅の4%
よくあるタイプですね。それでは始めましょう!
完成コードと実装結果
コード
<header class="ly_header"> <!-- ① -->
<div class="ly_header_inner"> <!-- ① -->
<nav class="bl_headerContents">
<div class="bl_headerContents_logo">
<a href="index.html">
<img src="https://www.blog.hy-webc.com/wp-content/uploads/2021/10/logo.png" alt="Logo" width="135" height="26">
</a>
</div>
<button class="bl_headerContents_gnavBtn">
<i class="fas fa-bars"></i> <!-- ⑥ -->
<span class="sr-only">MENU</span> <!-- ⑥ -->
</button>
</nav>
</div>
</header>
/* ヘッダーのレイアウト用:ヘッダーの高さと左右マージンを決める */
.ly_header {
height: 80px; /* ② */
background-color: #fff;
border-bottom: 1px solid #aaa;
}
.ly_header_inner {
width: min(92%, 1000px); /* ③ */
margin: auto; /* ③ */
height: 100%;
}
/* 以下、ヘッダーの中身を記述 */
.bl_headerContents {
display: flex; /* ④ */
justify-content: space-between; /* ④ */
align-items: center; /* ④ */
height: 100%;
}
/* 右端の要素は右マージンを常に0とする */
.bl_headerContents > *:last-child { /* ⑤ */
margin-right: 0;
}
/* ハンバーガーメニューのスタイル */
.bl_headerContents_gnavBtn {
padding: 0;
outline: none;
border: none;
background: transparent;
cursor: pointer;
color: #aaa;
font-size: 30px;
}
実装結果
See the Pen header(original) by hori-suke (@hori-suke) on CodePen.
各プロパティの説明
①<header class=”ly_header”>, <div class=”ly_header_inner”>
この2つのクラスは、ヘッダーのレイアウトを決めるためのものです。<header class="ly_header">
がヘッダーの一番外側を囲み、<div class="ly_header_inner">
がその内側を囲みます。そして最も内側に、ヘッダーのコンテンツ<nav class="bl_headerContents">
を入れ込む形となります。
ヘッダー全体の構造としては以下のとおりです。
このように、レイアウト用の枠組みと、コンテンツそのものを分離することで、CSSが管理しやすくなります(ヘッダーに限らず、あらゆるパーツで使える考え方です)。
ここで重要なのは、コンテンツbl_headerContents
では、レイアウトに関わる設定(margin
など)をしないことです。つまり、常に親要素の幅いっぱいに広がる状態にしておきます。コンテンツの幅を変えたい場合は外側のレイアウト用のクラスly_header_inner
の設定を変えます(具体的には、後述のwidth: min(92%, 1000px)
の数値を変えます)。こうすることで、それぞれのクラスを使いまわしのきく汎用的なものにしておくことが出来ます。
なお、クラス名についてですが、先頭のly_
はlayoutの先頭の2文字、bl_
はblockの先頭の2文字からとっています。このようにクラス名の先頭に役割を示す文字をつけることで、クラスの役割分担をはっきりさせ、管理しやすくなります。(この記事では、PRECSSの命名規則をつかっています。)
②height: 80px;
ヘッダーの高さを決めています。ここでは直接80pxと固定値で指定していますが、コンテンツの高さが伸縮することが想定される(ブラウザのフォントサイズ変更などで)場合は、height
指定の代わりに、上下のpadding
指定がよいでしょう。
③width: min(92%, 1000px); margin: auto;
IE11を除くブラウザでは、min()関数が使えるようになっています。width: min(92%, 1000px)
の意味は、「親要素幅の92%とするが、最大幅は1000pxとする」です。つまり、ブラウザ幅が1080pxを超えると、コンテンツが1000px固定となり、左右のマージンだけが増えていくイメージですね。min()の中に書いた数字のいずれか小さい値が採用されるので、上記のような動きとなっています。
従来、IE11に対応した書き方では、width: 92%; max-width: 1000px;
と2つに分けて書く必要がありましたが、IE11非対応が可能な案件では、min()関数を使うことで1行で書くことができます。
続いて、margin: auto;
とすることで中央寄せとなります。左右の余白は、100% – 92% = 8%の半分ですので、それぞれ4%となります。
④display: flex; justify-content: space-between; align-items: center;
この3つのプロパティは、要素を横並びにしたいときによく使うやつですね。
display: flex;
で、ロゴとボタンが横並びになります。
justify-content: space-between;
で、2つの要素が左右両端揃えになります。
align-items: center;
で縦方向の配置が中央揃えになります。
上記の3点セットは、使わない案件はないくらい頻出ですので、レイアウトを見たときにパッと思いつくようにしておくと便利です。
なお、この部分は、Gridを使ってレイアウトすることも可能ですが、Gridは標準で縦並びになり、横並びにするためのプロパティをわざわざ書かなければいけなかったりするので、この場合はFlexを使うのが便利です。Gridを覚えると、やたらと至るところで使いたくなりますが、目的と手段を間違えないようにしましょう(自戒含む)。
⑤.bl_headerContents > *:last-child
コンテンツの右端の要素の右マージンを常に0にする指定です。これは何のために書いているかというと、将来の拡張や保守を見据えたものです。
今回、コンテンツの右側の要素はハンバーガーボタンのみですが、将来的には検索ボタンや電話番号などの要素を追加していくことも想定されます。
すると、図らずとも右側にmarginが設定されている要素が追加されると、コンテンツがmarginの分だけ左寄りにずれてしまうことになります。
これを防ぐため、あらかじめコンテンツの右端の要素の右マージンを常に0にリセット指定をしています。こういうコードをサラッと書けるようにしたいですね。
⑥<i class=”fas fa-bars”></i>, <span class=”sr-only”>MENU</span>
ハンバーガーボタンの表示は、<i class="fas fa-bars"></i>
として、Font Awesomeの3本線アイコンを表示しています。Font Awesomeの使い方は、外部記事ですが、下記を参考にしてください。
さらに、スクリーンリーダー用にMENUというテキストを追加し、<span class="sr-only">MENU</span>
でマークアップしています。sr-only
は、Font Awesome内に用意されているクラスで、画面非表示にしつつ、スクリーンリーダーでの読み上げに対応させることができるようになります。
おわり
今回は、ヘッダーの実装方法を紹介しました。私も慣れない頃は、ヘッダーの実装だけで一日費やしてしまい、そのレスポンシブ対応で更にもう一日・・・ということもありました(遠い目)。
しかし、今回ご紹介したようにレイアウト用のクラスとコンテンツ用のクラスを使い分けることに慣れると、コードの見通しが圧倒的に良くなると同時に、コードの再利用も簡単にできるようになってきますので、ぜひ使えるようになっておきましょう!