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 の状態なら、次の順序で実行され、

  1. background-position (0s)
  2. background-size (0.4s)
  3. transform (0.8s)

逆に、input:checked でない状態なら、次の順序で実行されます。

  1. transform (0s)
  2. background-size (0.4s)
  3. 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 による表示

See the Pen CSS simple hamburger button by nov (@numerofive) on CodePen.

アニメーションが面白いと、意味なく開閉しちゃいますよね。

関連記事