【css】ハンバーガーメニューをコピペなしで0から作る

ハンバーガーメニューを0から作る

初心者の登竜門たる、ハンバーガーメニュー。

「コピペして作ってみたけど、よう分からん!」

という人に、0から解説します。

1ではなく、ゼロからです。

  • 仕組みを知りたい
  • コピペなしで作りたい

こんな奇特な考えをお持ちの方はご覧ください。

ハンバーガーメニューのみならず、コードを書く実力もつきます。

ハンバーガーメニュー、作り方の流れ

完成イメージは、こちら。

※ハンバーガーをクリックしてみてください。

top
about
access

それっぽいやつですよね。

仕組みさえ分かれば、こんな簡易なものも作れます。

で、作り方ですが、流れはザッとこんな感じ。

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

※この手順は、何回も出てきます。

さっそく、「inputとlabel」をご覧ください。

inputとlabelをひもづける

はい、もうたった今見た手順です。

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

(手順1) inputとlabelをひもづける

まずは<input>から書きます。

typeはcheckboxとしましょう。

※typeはhtml属性の1つで、type属性と言います。

<input type="checkbox">

type="checkbox"とすると、チェックボックスが出てきます。

クリックかタップしてください。

「1回押すとチェックが入り、もう1回押すと消える」

いわゆるON-OFF機能

これが、<input>の動きです。

意外とだいじなんで、覚えときましょう〜

【参考記事】inputのcheckはON-OFF機能

次に<label>を書いて、<input>とひもづけます。

<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>

「ハンバーガー」をクリックしてください。

□にチェックが入ったと思います。

<label>を使うと、□をクリックしなくてもチェックが入るようになります。

これをひもづけると表現するみたい。

もちろん、□をクリックしてもチェックはつきますよ。

ひもづけをしているのは、<input>のidと<label>のforで使っているcheckです。

<input type="checkbox" id="check">
<label for="check">ハンバーガー</label>

<input>と<label>はオッケーでしょうか?

次は、□を消します。

【参考記事】labelの使い方

inputを非表示にする

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

(手順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でハンバーガーのアイコンを作る

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

(手順3)labelでハンバーガーのアイコンを作る

3本線は、<label>の中に書いた<span>と擬似要素(before、after)で作ります。

  • <span>
  • before
  • after

※うすい青色が<label>のエリア

というわけで、先に<label>の大きさを決めます。

その前に先ほどは、

<label for="check">ハンバーガー</label>

としてましたが、「ハンバーガー」を消して<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: 3pxwidth: 25pxに線の外枠を作りました。

で、この縦3pxと幅25pxのエリアの背景色をつけることで、線に見えるというカラクリです。

続いて、擬似要素のbeforeafterで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を<label>に。

<span>と擬似要素にはposition: absoluteを指定。

span,span::before,span::after {

}

ってとこです。

で、これでは3本の線に同じ指定をしているので、線が重なってしまいます。

なので、線を下げるために、2本目を下に8px移動させるtop: 8px(before)

3本目を下に16px移動させる、top: 16px(after)としました。

ハンバーガーメニューの3本線

これでハンバーガーアイコンのできあがりです。

線の作り方は、理解していただけたでしょうか。

次は手順4です。

長いので、休憩はご自由にどうぞ。

【参考記事】positionの使い方

ナビメニューを作る

再び、ハンバーガーメニューを作る流れをご覧ください。

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

(手順4)ナビメニューを作る

にいく前に。

完成形をもう1度見てみましょう。

top
about
access

ハンバーガーのアイコンが右側にありますね。

ですので、メニューを作る前にこれを移動させましょう。

ちなみにハンバーガーメニューはヘッダー内で作るっていう前提で話を進めています。

ホント、今さら過ぎてすみません。

そして先ほど、ハンバーガーアイコンである<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;
}

top
about
access

<ul>や<li>には、指定をしていません。

positon: fixedは、画面に対して位置を固定するものでした。

topは画面1番上から50pxの位置で、left: 0は画面左端。

fixedを指定することで、縦にスクロールしてもナビメニューは常に表示され続けます。

【参考記事】【css】positionの使い方の「fixed」

また、幅(90%)や高さ(100%)も画面が基準となります。

position: fixedは画面を基準にして要素を配置する。

z-indexの指定は、このナビメニューが1番前に出るためのものです。

と、こんな感じです。

ナビメニューの作り方は、大丈夫そうですか?

やっとこそ、次でさいご。

手順5です。

ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

再び、再びハンバーガーメニューを作る流れは、こちら。

  1. inputとlabelをひもづける
  2. inputを非表示にする
  3. labelでハンバーガーのアイコンを作る
  4. ナビメニューを作る
  5. ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

ナビメニューを引っ込める

手順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%);
}

top
about
access

ナビメニューが消えました。

理由は、transform: translateX(-110%)としたから。

translateX(-110%)はマイナス値なので、今いる位置より左側に移動します。

110%は、<nav>自体の幅の110%です。

例えば、幅が300pxの場合だと330px移動するので、画面の中からは消えます。

言い換え変えると、左側に隠れてるってなるかと。

translate

checkedでナビメニューを出現させる

(手順5)ハンバーガーアイコンのクリックで、ナビメニューが出たり引っ込んだりする

ハンバーガーアイコンのクリックで、見える位置に戻します。

ここで使うのが、checked

<input>のid名がcheckのため、#check:checkedとします。

あっ、ちなみに「:」と「checked」の間には、スペースを入れないようにしましょう。

指定が効かなくなるので。

また、label:checkedともしないよう、気をつけてくださいね。

あくまでも、チェック機能ってのは<input>にだけあるので。

#check:checked ~ nav {
  transform: translateX(0%);
} 

上記は、<input>にチェックが入った時、ナビメニュー<nav>がもとの位置に戻る指定です。

「ん?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%);
} 

と書けます。

【参考記事】子孫要素に限定して指定するの「兄弟要素に指定」

top
about
access

これでハンバーガーアイコンを押すたび、ナビメニューが出たり引っ込んだりします。

ちなみに、この#check:checked ~ navの指定を検証画面で見るなら、ハンバーガーメニューをクリック。

ナビメニューを表示させた状態で、htmlコードの画面の<nav>をクリック。

すると指定内容が確認できます。

【参考記事】chrome検証 〜初心者でも、安心して使いこなせる〜の「checked」

というわけで、ハンバーガーメニューの完成です。

いやー、長かった。

説明してる自分も色々混乱してきそうでした。

参考サイト

この記事は、HTML Living StandardCSS3をもとに書きました。

HTML Living Standardはhtmlの、CSS3はcssのルールブックみたいなものです。

両方とも、その最新版です。

まとめ

1つ1つ理解するとなると、大変ですよね。

それくらい、ハンバーガーメニューにはいろいろな要素が入っています。

ただ、仕組みさえ理解していればうまくいかない時も自己修正が可能です。

流れだけでもつかんでいただけたらと思います。

タイトルとURLをコピーしました