HTMLとCSSのみの簡単なハンバーガーボタンの作り方
多くの情報をコンパクトにまとめられるハンバーガーメニュー (ドロワー) ですが、そこで使用される三本線のハンバーガーボタンの作り方は多くあります。
今回は、HTMLとCSSのコード量が少ない、シンプルなハンバーガーボタンの作り方を紹介します。
ハンバーガーボタンのHTMLコード
<input type="checkbox" id="checkbox" />
<label for="checkbox"></label>
ハンバーガーボタンに必要なHTMLは、チェックボックスと、それに関連付けされたラベルだけです。このラベルをハンバーガーボタンにしていきます。
ハンバーガーボタンのCSSコード
まずは、表示しておきたくないチェックボックスを隠します。
input {
clip-path: inset(50%);
position: fixed;
inset-block-start: 0;
}
次に、ラベルをハンバーガーボタンにしていきますが、ハンバーガーの三本線を作る前にラベルの形を整えます。
label {
border: solid 2px;
border-radius: 50%;
box-sizing: border-box;
cursor: pointer;
display: block;
height: 32px;
width: 32px;
}
直径32pxのまんまるボタンです。まんまるボタンはハンバーガーボタン、ちいさなボタンでメニューがひらく!
そして、要のハンバーガーはbackgroundプロパティで作っていきます。
label {
background:
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% calc(50% - 6px) / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% calc(50% + 6px) / 16px 2px;
…
}
これで、縦2px、横16pxの線が、4pxの間隔を空けて縦に並ぶ、ハンバーガーボタンの出来上がりです。
ハンバーガーメニューが開いているとき
ハンバーガーメニューが開いているときは、バツマークに変わるようにしてみます。
input:checked ~ label {
background:
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 2px 16px;
transform: rotate(45deg);
}
:checked擬似クラスと兄弟セレクタ (~
) を組み合わせます。これと同様の方法で、ハンバーガーメニューの開閉も行います。
ここまでのCSSコードのまとめ
ここまでのCSSコードをまとめると、以下のようになります。
input {
clip-path: inset(50%);
position: fixed;
inset-block-start: 0;
}
label {
background:
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% calc(50% - 6px) / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% calc(50% + 6px) / 16px 2px;
border: solid 2px;
border-radius: 50%;
box-sizing: border-box;
cursor: pointer;
display: block;
height: 32px;
width: 32px;
}
input:checked ~ label {
background:
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 16px 2px,
linear-gradient(currentcolor, currentcolor) no-repeat 50% 50% / 2px 16px;
transform: rotate(45deg);
}
シンプルですよね。
ハンバーガーボタンにアニメーションを加える
シンプルすぎるので、アニメーションを加えてみます。
background-positionプロパティ、background-sizeプロパティ、transformプロパティは、transitionプロパティでアニメーションさせることができます。
backgroundプロパティの値のうち、アニメーションできないプロパティと、アニメーションできるプロパティを分け、transitionプロパティを設定します。
label {
/* アニメーションできない値 */
background:
linear-gradient(currentcolor, currentcolor) no-repeat /* バツマークの線1 */,
linear-gradient(currentcolor, currentcolor) no-repeat /* バツマークの線2 + ハンバーガーの線1 */,
linear-gradient(currentcolor, currentcolor) no-repeat /* ハンバーガーの線2 */,
linear-gradient(currentcolor, currentcolor) no-repeat /* ハンバーガーの線3 */;
/* アニメーションできる値 */
background-position:
50% 50% /* バツマークの線1 */,
50% 50% /* バツマークの線2 + ハンバーガーの線1 */,
50% calc(50% - 6px) /* ハンバーガーの線2 */,
50% calc(50% + 6px) /* ハンバーガーの線3 */;
background-size:
0px 0px /* バツマークの線1 */,
16px 2px /* バツマークの線2 + ハンバーガーの線1 */,
16px 2px /* ハンバーガーの線2 */,
16px 2px /* ハンバーガーの線3 */;
/* アニメーションの設定 */
transition:
transform 0.4s 0s,
background-size 0.4s 0.4s,
background-position 0.4s 0.8s;
…
}
input:checked ~ label {
/* アニメーションできる値 */
background-position:
50% 50% /* バツマークの線1 */,
50% 50% /* バツマークの線2 + ハンバーガーの線1 */,
50% 50% /* ハンバーガーの線2 */,
50% 50% /* ハンバーガーの線3 */;
background-size:
2px 16px /* バツマークの線1 */,
16px 2px /* バツマークの線2 + ハンバーガーの線1 */,
0px 0px /* ハンバーガーの線2 */,
0px 0px /* ハンバーガーの線3 */;
transform: rotate(135deg);
/* アニメーションの設定 */
transition:
background-position 0.4s 0s,
background-size 0.4s 0.4s,
transform 0.4s 0.8s;
}
ポイントとなるのは、transition-delayプロパティ (transitionプロパティの3つ目の値) の設定です。
transition-delayプロパティはアニメーションの実行を遅らせるプロパティで、遅らせる秒数 (s
) を操作することで、逆再生させたようなアニメーションが設定できます。
上記のコードでは、チェックボックスが input:checked
の状態なら、次の順序で実行され、
- background-position (0s)
- background-size (0.4s)
- transform (0.8s)
逆に、input:checked
でない状態なら、次の順序で実行されます。
- transform (0s)
- background-size (0.4s)
- background-position (0.8s)
background-positionプロパティ、background-sizeプロパティ、transformプロパティの各値と、transitionプロパティによるアニメーションの実行順序を操作することで、色々なアニメーションが設定できるので、試してみてください。
最終的なCSSコードのまとめ
input {
clip-path: inset(50%);
position: fixed;
inset-block-start: 0;
}
label {
background:
linear-gradient(currentcolor, currentcolor) no-repeat,
linear-gradient(currentcolor, currentcolor) no-repeat,
linear-gradient(currentcolor, currentcolor) no-repeat,
linear-gradient(currentcolor, currentcolor) no-repeat;
background-position:
50% 50%,
50% 50%,
50% calc(50% - 6px),
50% calc(50% + 6px);
background-size:
0px 0px,
16px 2px,
16px 2px,
16px 2px;
transition:
transform 0.4s 0s,
background-size 0.4s 0.4s,
background-position 0.4s 0.8s;
border: solid 2px;
border-radius: 50%;
box-sizing: border-box;
cursor: pointer;
display: block;
height: 32px;
width: 32px;
}
input:checked ~ label {
background-position:
50% 50%,
50% 50%,
50% 50%,
50% 50%;
background-size:
2px 16px,
16px 2px,
0px 0px,
0px 0px;
transform: rotate(135deg);
transition:
background-position 0.4s 0s,
background-size 0.4s 0.4s,
transform 0.4s 0.8s;
}
CodePen による表示
〆
アニメーションが面白いと、意味なく開閉しちゃいますよね。