今回はスマートフォンやタブレット向けのWebサイトで採用されることの多いナビゲーションUI「ハンバーガーメニュー」の作り方をまとめました。
最近はボトムナビゲーションも増えてきて、ハンバーガーメニュー不要論など見かけること増えてきましたが、まだまだ採用されているところも多く現役なUIかと思います。
今回はなるべく簡単なパターンで実装できる方法を僕なりにまとめましたので勉強中の方は是非ご覧ください!
今回実装する完成形
レスポンシブ対応でヘッダーがハンバーガーアイコンに変化します。
リセットCSS
先に面倒なデフォルトスタイルを消しておきます。
リセットCSSはデフォルトのスタイリングをほぼ無くすことができる「destyle.css」から一部を抜粋してます。
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
::before , ::after {
box-sizing: inherit;
}
button {
margin: 0;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
color: inherit;
vertical-align: middle;
text-align: inherit;
font: inherit;
-webkit-appearance: none;
appearance: none;
}
メニューリストのスタイリング
分かりやすいようにまずメニューから作成します。
<nav>
<ul class="menu">
<li class="menu-list">メニュー1</li>
<li class="menu-list">メニュー2</li>
<li class="menu-list">メニュー3</li>
<li class="menu-list">メニュー4</li>
<li class="menu-list">メニュー5</li>
</ul>
</nav>
載せてませんが、jQueryを使うのでCDNコードはHTMLのbodyの閉じタグ前に読み込んでます!詳しくはこちらから↓
メニューエリアのCSSは下記の通り。
.menu {
width: 70%;
height: 100vh;
margin-left: auto;
/* メニューを縦に */
display: flex;
flex-direction: column;
color: #efefef;
background-color: rgba(167, 148, 58, 0.7);
transition: .3s;
}
メニューは表示範囲内のリストが縦並びに配置されるように、flex-direction: columnを指定しています。
あとはリストの中身を整えます。liタグ一つずつに幅・高さ100%を指定してます。また、Flexboxで「メニューn」のテキストをliタグ内中央に配置します。
.menu-list {
width: 100%;
height: 100%;
/* メニューテキスト位置をリスト内中心に */
display: flex;
justify-content: center;
align-items: center;
}
あとはメニューエリアを表示させないようにpositionで画面外に配置する記述を追加します。(メニューエリア幅以上のマイナス指定が必要です)
.menu {
/* メニューの位置マイナス指定で画面外に */
position: fixed;
right: -70%;
width: 70%;
height: 100vh;
/* メニューを縦に */
display: flex;
flex-direction: column;
color: #efefef;
background-color: rgba(167, 148, 58, 0.7);
transition: .3s;
}
上の記述を追加するとメニューが画面から消えたはずです。
バーガーボタンのスタイリング
次にハンバーガーアイコンを作成します。
<button type="button" class="btn js-btn">
<span class="btn-line"></span>
</button>
ボタンをdivやinputで作るやり方を見ることがありますが、これだとPCのタブキー操作でフォーカスが当たりません。アクセシビリティを考慮すると、クリッカブルな要素はaタグやbuttonタグで実装したほうがいいため、今回はbuttonタグで実装します。
※今回使用するdestyle.cssはbuttonタグのフォーカスも消してしまうので、必要に応じて修正する必要があります。
また、バーガーの線をspanタグで実装する方法もありますが、HTMLから余計な記述を除外するために今回はCSSの擬似要素で対応する方法をとります。
.btn {
/* ボタンの配置位置 */
position: fixed;
top: 32px;
right: 16px;
/* ボタンの大きさ */
width: 48px;
height: 48px;
/* 最前面に */
z-index: 10;
background-color: red; /* わかりやすいように */
}
一番下のbackground-colorはあとで消します。今回はボタンを右上に配置するのでpositionで指定します。
次に肝心のバーガー線ですが、spanタグに指定したクラスに幅と高さを持たせて色をつけます。
/***** 真ん中のバーガー線 *****/
.btn-line {
display: block;
position: relative; /* バーガー線の位置基準として設定 */
width: 100%; /* 線の長さと高さ */
height: 4px;
background-color: #d6d5d5; /* バーガー線の色 */
transition: .2s;
}
線に大きさを指定するのでdisplay: blockの記述が必要です。
あとは上下の線の基準にしたいのでposition: relativeを指定します。
線自体の大きさは今回btnクラスで指定している(図だと赤色の領域)に対して幅100%としています。
あとは中心線に対して上下線は擬似要素で指定します。
/****** 上下のバーガー線 *****/
.btn-line::before,
.btn-line::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background-color: #d6d5d5;
transition: .5s;
}
.btn-line::before {
/* 上の線の位置 */
transform: translateY(-16px);
}
.btn-line::after {
/* 下の線の位置 */
transform: translateY(16px);
}
beforeが上、afterが下の線です。当然ですが幅・高さの指定も必要ですが、元要素と同じにしたい時は上記のように100%で指定します。
上下の線の位置指定はpositionだと崩れやすいのでtransform: translateYで指定しています。(このあたりで.btnのbackground-color: redは消しておいてもいいです。)
jQueryで動きをつける
jQueryはクラスのつけ外しにしか使わないので非常にシンプルです。
$(function () {
$('.js-btn').on('click', function () { // js-btnクラスをクリックすると、
$('.menu , .btn-line').toggleClass('open'); // メニューとバーガーの線にopenクラスをつけ外しする
})
});
コメントの通りですが、js-btnクラスをクリックすると、toggleClassメソッドでメニューとバーガーの線、二つのクラスに対してopenクラスをつけ外しさせます。
非表示のメニューを表示させる
まずはpositionで画面外に配置していた.menuクラスにopenクラスを付与させて、位置を0に戻します。今回で言うと -70% → 0 と移動させることになります。
.menu.open {
right: 0;
}
ハンバーガーアイコンを変化させる
次にバーガーの線に変化を加えます。
/***** メニューオープン時 *****/
.btn-line.open {
background-color: transparent; /* 真ん中の線を透明に */
}
.btn-line.open::before ,
.btn-line.open::after {
content: "";
background-color: #333; /* 上下の線の色を変える */
transition: .2s;
}
.btn-line.open::before {
transform: rotate(45deg); /* 上の線を傾ける */
}
.btn-line.open::after {
transform: rotate(-45deg); /* 下の線を傾ける */
}
transparentは色の値で透明にさせることができます。真ん中の線を透明にさせます。
上下の線はtransform: rotateで傾けます。上は(45deg)、下は(-45deg)にしました。
必須ではないですが、今回は線の色も白→黒と変化を与えています。
これでハンバーガーメニューの実装の完成です。
コードまとめ
最後に改めてデモサイトのコードをまとめておきます。
- リスト内にhover装飾
- メディアクエリでPC時はバーガーボタン非表示+ナビを横並び
この2点は本題と関係無かったので説明は割愛していますが、下のコードには反映させてます。あと背景画像は消してます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<button type="button" class="btn js-btn">
<span class="btn-line"></span>
</button>
<nav>
<ul class="menu">
<li class="menu-list">メニュー1</li>
<li class="menu-list">メニュー2</li>
<li class="menu-list">メニュー3</li>
<li class="menu-list">メニュー4</li>
<li class="menu-list">メニュー5</li>
</ul>
</nav>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script src="script.js"></script>
</body>
</html>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
::before , ::after {
box-sizing: inherit;
}
button {
margin: 0;
padding: 0;
outline: 0;
border: 0;
border-radius: 0;
background: transparent;
color: inherit;
vertical-align: middle;
text-align: inherit;
font: inherit;
-webkit-appearance: none;
appearance: none;
}
/**************** 以下、ハンバーガーボタンのスタイリング ****************/
.btn {
/* ボタンの配置位置 */
position: fixed;
top: 32px;
right: 16px;
/* 最前面に */
z-index: 10;
/* ボタンの大きさ */
width: 48px;
height: 48px;
}
/***** 真ん中のバーガー線 *****/
.btn-line {
display: block;
/* バーガー線の位置基準として設定 */
position: relative;
/* 線の長さと高さ */
width: 100%;
height: 4px;
/* バーガー線の色 */
background-color: #d6d5d5;
transition: .2s;
}
/***** 上下のバーガー線 *****/
.btn-line::before , .btn-line::after {
content: "";
/* 基準線と同じ大きさと色 */
position: absolute;
width: 100%;
height: 100%;
background-color: #d6d5d5;
transition: .5s;
}
.btn-line::before {
/* 上の線の位置 */
transform: translateY(-16px);
}
.btn-line::after {
/* 下の線の位置 */
transform: translateY(16px);
}
/***** メニューオープン時 *****/
.btn-line.open {
/* 真ん中の線を透明に */
background-color: transparent;
}
.btn-line.open::before , .btn-line.open::after {
content: "";
background-color: #333;
transition: .2s;
}
.btn-line.open::before {
/* 上の線を傾ける */
transform: rotate(45deg);
}
.btn-line.open::after {
/* 上の線を傾ける */
transform: rotate(-45deg);
}
/**************** ここまで、ハンバーガーボタンのスタイリング ****************/
/**************** 以下、メニューのスタイリング ****************/
.menu {
/* メニューを縦に */
display: flex;
flex-direction: column;
position: fixed;
/* メニューの位置マイナス指定で画面外に */
right: -70%;
width: 70%;
height: 100vh;
background-color: rgba(167, 148, 58, .7);
color: #efefef;
transition: .3s;
}
.menu-list {
/* メニューテキスト位置をリスト内中心に */
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.menu-list:hover {
background-color: rgba(255, 255, 255, .5);
color: #333;
cursor: pointer;
transition: .3s;
}
/***** メニューオープン時位置0にして画面内に *****/
.menu.open {
position: absolute;
right: 0;
}
/* 600px以上はハンバーガーボタン非表示、ヘッダー固定 */
@media screen and (min-width: 600px) {
.btn {
display: none;
}
.menu {
/* メニューを横に */
display: flex;
flex-direction: row;
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100px;
}
}
/**************** ここまで、メニューのスタイリング ****************/
一応補足しておくと、PC時のスタイル指定はラスト16行の記述だけです。btnクラスを消したのと、menuクラスをcolumnからrowにして横並びにしただけです。
$(function () {
$('.js-btn').on('click', function () { // js-btnクラスをクリックすると、
$('.menu , .btn-line').toggleClass('open'); // メニューとバーガーの線にopenクラスをつけ外しする
})
});
コードをコピペして、画像や値を変えながら自分なりに変化を見てみると理解も深まると思います。
ハンバーガーメニューはバーガーボタンの動かし方と、メニュー表示のさせ方で工夫ができます。
バーガーボタンだけ抜粋したサンプル集も作っているのでこちらもよかったらご覧ください↓
PENGIN BLOGで提供している無料のコーディング課題に沿ったハンバーガーボタンの実装方法についてはこちらの記事にまとめています。
他にも汎用的なUIデザインのコーディング方法についてまとめているので、良かったらカテゴリからご覧ください!(下のはモーダルウィンドウの作り方です)
また、当記事を読まれている方の中にはWeb制作初学者の方もいるかと思います。デザインやコーディングの基礎知識を学びたい方向けの記事を用意しているので是非見ていってください!
PENGIN無料コーディング課題
オススメ書籍紹介
オススメUdemy講座紹介