初心者の登竜門と言える、ハンバーガーメニュー。
「コピペして作ってみたけど、よう分からん!」
という人に0から解説します。
1ではなく、ゼロからです。
- コピペなしで作りたい
- コードの内容を理解したい
こんな奇特な考えをお持ちの方は、ご覧ください。
ハンバーガーメニューのみならず、コードを書く実力もつきます。
ハンバーガーメニュー、作り方の流れ
完成イメージは、こちら。
※ハンバーガーをクリックしてみてください。
それっぽいやつですね。
仕組みさえ分かれば、こんな簡易なものも作れます。
作り方ですが、流れはザッとこんな感じ。
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ナビメニューが出たり引っ込んだりする
※この手順は、何回も出てきます。
さっそく作ってみましょう。
inputとlabelをひもづける
はい、もうたった今見た手順です。
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする
(手順1) inputとlabelをひも付ける
まずは<input>から書きます。
typeはcheckboxとしましょう。
※typeはhtml属性の1つで、type属性と言います。
<input type="checkbox">
type="checkbox"
とすると、チェックボックスが出てきます。
クリックかタップしてください。
「1回押すとチェックが入り、もう1回押すと消える」
いわゆるON-OFF機能。
このON-OFFで、ハンバーガーメニューが出たり引っ込んだりします。
【参考記事】inputとlabelの役割と違いについて解説
次に<label>を書き、<input>とひも付けましょう。
ひも付けは、<input>のidと<label>のforのcheckで行います。
<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>
「ハンバーガー」の文字をクリックしてください。
□にチェックが入るはずです。
ひも付けると、□をクリックしなくてもチェックが入ります。
これが<label>の役割です。
もちろん□をクリックしても、チェックはつきますよ。
<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>
<input>と<label>のひも付けは、大丈夫でしょうか?
次は、□を消します。
【参考記事】inputとlabelの役割と違いについて解説
inputを非表示にする
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ナビメニューが出たり引っ込んだりする
(手順2)inputを非表示にする
手順1でクリックすると、チェックが入るようにした「ハンバーガー」の文字。
そして、この「ハンバーガー」が、手順3で3本線になります。
一方、□はクリックする必要がなくなりました。
なので、<input>を非表示にします。
<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>
input {
display: none;
}
「ハンバーガー」をクリックしてください。
見た目上は変化ありません。
display :none
で□を消したからですね。
しかし、
「ハンバーガー」をクリックすれば、その裏側では非表示の□にチェックがついたり外れたりしている
ってのが、ここのミソです。
と言っても、おそらく分かりにくいかと。
こちらで裏側の動きを再現しました。
<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>
input {
display: none;
}
非表示のinput↓
「ハンバーガー」を押すと、□にチェックが入ったり外れたりしますね。
「なるほどーっ!」と、なりませんか?
個人的には、ここがおもしろいんですが…
というわけで、ここまで<input>と<label>のひもづけ。
それと、消した□が裏側で動いているのを、理解してもらえたらと思います。
次は手順3。
<label>でハンバーガーのアイコンを作ります。
labelでハンバーガーのアイコンを作る
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ナビメニューが出たり引っ込んだりする
(手順3)labelでハンバーガーのアイコンを作る
3本線は、<label>の中に書いた<span>と擬似要素(before、after)で作ります。
- <span>
- before
- after
※うすい青色が<label>のエリア
というわけで、先に<label>の大きさを決めます。
その前に先ほどは、
<label for="check">ハンバーガー</label>
としてましたが「ハンバーガー」を消し、代わりに<span>を入れましょう。
<label for="check"><span></span></label>
こうですね。
それでは、改めて<label>の大きさを指定します。
<input type="checkbox" id="check">
<label for="check"><span></span></label>
label {
display: inline-block;
width: 25px;
height: 22px;
}
/* 背景色を入れています */
<label>はインライン要素です。
なので、幅と高さを指定できません。
というわけで、ブロックかインラインブロックに変換します。
ここでは、インラインブロックにしました。
で、思い出していただきたいのですが…
<label>の青のエリアをクリックすると、非表示の□にチェックがつきます。
ですから、3本線はあくまで装飾であるとご理解ください。
ここも大丈夫でしょうか。
【参考記事】ブロック要素とインライン要素の違い
3本線を作る
今度は、<span>を使って線を作ります。
<span>もインライン要素です。
ブロック要素に変換しましょう。
<input type="checkbox" id="check">
<label for="check"><span></span></label>
span {
display: block;
height: 3px;
width: 25px;
background-color: #777; /* 濃いグレー */
}
<label>のエリアの1番上に線がありますね。
横線は、height: 3px
とwidth: 25px
で作っています。
そのエリアに背景色をつけると、横線に見えるというカラクリです。
続いて、before
とafter
で2・3本目の線を作りましょう。
<input type="checkbox" id="check">
<label for="check"><span></span></label>
label {
position: relative;
}
span,span::before,span::after {
display: block;
height: 3px;
width: 25px;
background-color: #777;
content: "";
position: absolute;
}
span::before {
top: 8px;
}
span::after {
top: 16px;
}
2つ注目する箇所があります。
1つはcontent: ""
。
<span>の中身がカラだと擬似要素に指定した内容が効きません。
ですので、この記述を加えました。
もう1つはpositon
です。
<label>の中に3本線を作るので、position: relative
を指定。
<span>と擬似要素には、position: absolute
を指定しました。
しかし下記コードだと、
- <span>
- before
- after
に同じ指定をしているので、線が重なっている状態。
span,span::before,span::after {
display: block;
height: 3px;
width: 25px;
background-color: #777;
content: "";
position: absolute;
}
ですので、2本目を下へ8px移動させるためtop: 8px(before)
。
3本目を下へ16px移動させる、top: 16px(after)
としました。
span::before {
top: 8px;
}
span::after {
top: 16px;
}
これでハンバーガーアイコンのできあがりです。
線の作り方は、理解していただけたでしょうか。
次は手順4です。
長いので、休憩はご自由にどうぞ。
【参考記事】positionの使い方
ナビメニューを作る
再び、ハンバーガーメニューを作る流れをご覧ください。
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ナビメニューが出たり引っ込んだりする
(手順4)ナビメニューを作る
と、その前に。
完成形をもう1度、ご覧ください。
ハンバーガーのアイコンが右側にありますね。
ですので、メニューを作る前にこれを移動させましょう。
ちなみにハンバーガーメニューはヘッダー内で作る前提で話を進めています。
ホント、今さら過ぎてすみません。
そして先ほど、<label>にはdisplay: inline-block
としました。
<header>
<input type="checkbox" id="check">
<label for="check"><span></span></label>
</header>
header {
text-align: right;
}
label {
display: inline-block;
}
※青色の背景を消しました。
なので、親であるヘッダーにtext-align: right
を指定。
そうすると、子である<label>が右側へ移動しました。
インラインブロックだとtext-align
が効くので、こうなります。
ほかの方法としたら<header>にposition :relative
。
<label>にposition: absolute
とするやり方があります。
このposition
で指定するのが、一般的かもしれません。
【参考記事】positionの使い方
(手順4)ナビメニューを作る
改めて、ここから手順4です。
コードを見てみましょう。
できるだけシンプルにしてるんですが、それでもちょい長めです。
うす目でご覧いただければ…
とりあえず、<nav>にだけ注目!
で、<nav>でグレーの背景を作ります。
<header>
<input type="checkbox" id="check">
<label for="check"><span></span></label>
<nav>
<ul>
<li><a href="">top</a></li>
<li><a href="">about</a></li>
<li><a href="">access</a></li>
</ul>
</nav>
</header>
nav {
position: fixed;
top: 50px;
left: 0;
z-index: 99;
width: 90%; /* 画面幅に対して */
height: 100%; /* 画面の高さに対して */
background-color: #f2f1f1;
}
<ul>や<li>には、指定をしていません。
positon: fixed
は、画面に対して位置を固定するものでした。
top
は画面1番上から50pxの位置で、left: 0
は画面左端。
fixed
を指定すると、縦にスクロールしてもナビメニューは表示され続けます。
【参考記事】【css】positionの使い方の「fixed」
クリックすると該当箇所にジャンプします。
また、幅(90%
)や高さ(100%
)も画面が基準となります。
z-index
の指定は、このナビメニューが1番前に出るためのものです。
ようやく次がさいご。
手順5です。
ナビメニューが出たり引っ込んだりする
見飽きたかもしれませんが、ハンバーガーメニューを作る流れはこちら。
- inputとlabelをひも付ける
- inputを非表示にする
- labelでハンバーガーのアイコンを作る
- ナビメニューを作る
- ナビメニューが出たり引っ込んだりする
translateでナビメニューを消す
手順5へ行く前に、ナビメニューを見えなくしましょう。
<header>
<input type="checkbox" id="check">
<label for="check"><span></span></label>
<nav>
<ul>
<li><a href="">top</a></li>
<li><a href="">about</a></li>
<li><a href="">access</a></li>
</ul>
</nav>
</header>
nav {
position: fixed;
top: 50px;
right: 0;
z-index: 99;
width: 90%;
height: 100%;
background-color: #f2f1f1;
transform: translateX(-110%);
}
ナビメニューが消えました。
理由は、transform: translateX(-110%)
としたから。
translateX(-110%)
はマイナス値なので、今いる位置より左側に移動します。
110%は、<nav>自体の幅の110%です。
例えば、幅が300pxの場合だと330px移動するので、画面の中からは消えます。
左側に隠れてるという方が正しいかもしれません。
checkedでナビメニューを出現させる
(手順5)ナビメニューが出たり引っ込んだりする
ハンバーガーアイコンのクリックで、見える位置に戻します。
ここで使うのが、checked
。
<input>のid名がcheckのため、#check:checked
とします。
ちなみに「:」と「checked」の間には、スペースを入れられません。
また、label:checked
と書かないよう、気をつけてください。
あくまでも、チェック機能は<input>にだけあるので。
<header>
<input type="checkbox" id="check">
<label for="check"><span></span></label>
<nav>
⌇
</nav>
</header>
#check:checked ~ nav {
transform: translateX(0%);
}
上記は<input>にチェックが入った時、ナビメニューがもとの位置に戻る指定です。
「ん?translateX(110%)なんじゃない」
と、思った方もいるかもしれません。
「-110%移動したから、110%戻らないともとの位置にはならない」
こう感じるはずです。
実際、translate
は移動という意味です。
ですが、
実態としては本来<nav>がいるべき場所から移動して、110%左の所に置きますよ
というのがtranslateX(-110%)
の指定の意味です。
ですので、もとの場所に置くならtranslateX(0%)
となります。
【参考記事】移動translateについて
ちなみに、#check: checked ~ nav
の「〜」は、兄弟要素に指定できるものです。
<header>
<input type="checkbox" id="check">
<label for="check"><span></span></label>
<nav>
⌇
</nav>
</header>
ご覧のように<input>と<nav>は同じ階層にありますね。
そんなわけで、
#check:checked ~ nav {
transform: translateX(0%);
}
と書けます。
【参考記事】子孫要素に限定して指定するの「兄弟要素に指定」
これでハンバーガーアイコンを押すたび、ナビメニューが出たり引っ込んだりします。
ちなみに、
「#check:checked ~ nav
の指定を検証画面で確認したい」
そんな時は、ハンバーガーアイコンをクリック。
ナビメニューを表示させた状態で、htmlコードの画面の<nav>をクリック。
すると、指定内容が確認できます。
【参考記事】chrome検証 〜初心者でも、安心して使いこなせる〜の「checked」
クリックすると該当箇所にジャンプします。
というわけで、ハンバーガーメニューの完成です。
いやー、長かった。
説明してる自分も混乱してきそうでした。
参考サイト
この記事は、HTML Living StandardとCSS3をもとに書きました。
HTML Living Standardはhtmlの、CSS3はcssのルールブックみたいなものです。
両方とも、その最新版になります。
まとめ
1つ1つ理解すると、大変ですよね。
それくらいハンバーガーメニューには、多くの要素が詰まっています。
しかし、仕組みを理解すれば、うまくいかない時も自己修正が可能です。
流れだけでも、分かってもえたらと思います。