🍔
【CSS】ハンバーガーメニューの基本
ハンバーガーメニューの基本的な作成方法のメモ書きです。
他に良いやり方が色々あると思いますが、学んだ方法を書き留めておきます。
結果
全体の流れ
ハンバーガーメニューをクリックしたら、jsで関数を実行し、htmlタグにopenクラスが追加されます。このクラスの有無によって、CSSでデザインを変えています。
HTML
<body>
<div class="content">
<nav class="nav">
<ul>
<li><a href="#">ハンバーガー</a></li>
</ul>
</nav>
<h2 class="text">右のボタンをクリック→</h2>
<button type="button" class="nav-button" onclick="navFunc()">
<!-- スクリーンリーダー用のテキスト -->
<span class="sr-only">MENUボタン</span>
</button>
</div>
</body>
- buttonタグに「onclick」を設定し、クリックされた際、JSの関数を実行する処理をしています
- スクリーンリーダーという「画面の表示内容を音声で読み上げるソフト」を使用している人のためのテキストを追加しています。これは、無くても動作します。
CSS
CSSは行が長いの、分けて説明
基本設定
@charset "UTF-8";
/* 変数 */
:root {
/* 色 */
--button: #222222;
}
:root.open {
--button: #ffffff
}
a {
color: inherit;
text-decoration: none;
}
a:hover {
opacity: 0.8;
}
- .openクラスがある場合は、ハンバーガーボタンの色を変化させています
- aタグの下線を消し、liタグの色で変化するようにしています
- aタグホバー時は、少し透明にしています
/* 基本設定 */
body {
font-size: 16px;
line-height: 1.8;
margin: 0;
height: 100vh;
}
h2 {
margin-top: 10px;
}
- bodyの大きさを画面全体に設定
- 余分なマージンの除去
- h2は、ハンバーガーメニューボタンとのズレ調整
/* コンテンツの設定 */
/* ハンバーガーメニューを右上に表示させる */
.content {
display: flex;
justify-content: end;
align-items: start;
text-align: center;
height: 100%;
}
/* スクリーンリーダー用のテキストを非表示 */
.sr-only {
border: 0;
position: absolute;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
}
- ハンバーガーメニューを右上に配置しています。
- スクリーンリーダーのテキストを非表示にしています。
- absoluteに設定し、幅を持たせないようにしています。
ボタンの作成
/* ナビゲーションボタン */
.nav-button {
box-sizing: content-box;
padding: 0px;
margin: 20px;
border: none;
outline: none;
background: none;
width: 40px;
height: 30px;
cursor: pointer;
color: var(--button);
}
.nav-button::before,
.nav-button::after {
content: '';
display: block;
height: 2px;
background-color: currentColor;
transform: translateY(15px);
transition: 0.3s ease-in-out;
}
.nav-button::before {
transform: translateY(-15px);
box-shadow: 0 15px currentColor;
}
-
メニューを開くボタンの作成
-
border・padding・outline・background といったボタンにデフォルトで値が入っているプロパティを除去
-
マージンで、表示位置の調整
-
widthで横幅の指定、ボタンの線の幅も変更される
-
heightで高さ指定、ボタンの間隔は変わらない
-
ボタンの間隔を変更する場合は、以下の[ ]内の値を変更する
transform: translateY([15px]); transform: translateY([-15px]); box-shadow: 0 [15px] currentColor;
-
-
cursorでカーソルを合わせたときの設定
-
colorで変数( —button )を設定
- .openクラスがある場合に、色を変更するため
-
.nav-button::before, ::after
- heightは線の太さを指定
- display: block; で描画
- transitionで「ボタンの開閉」に応じたアニメーションを設定
-
.nav-button::before
- box-shadowで真ん中の線を描画している
/* ナビゲーションメニュー:(閉じるボタン) */
.open .nav-button {
z-index: 1000;
}
.open .nav-button::before {
transform: rotate(-45deg);
box-shadow: none;
}
.open .nav-button::after {
transform: rotate(45deg);
box-shadow: none;
}
- メニューを閉じるボタンの作成
- z-indexで一番上に表示されるように指定
- transform: rotate()で✕ボタンを作成している
ナビゲーションメニューの表示
/* ナビゲーションメニュー:(閉じた状態) */
.nav {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 0;
height: 0;
left: 100%;
overflow: hidden;
color: transparent;
transition: 0.5s ease-in-out;
}
- 閉じた状態のとき
- display、justify-content、 align-itemsを指定し、表示の不具合を防ぐ
- 指定しないと、テキストが左上に移動してから閉じるというアニメーションになる
- position、left、overflow、colorでテキストを画面外に出し、見れないようにしている
- absoluteで要素の大きさを他の要素に影響しないようにしている
- transitionでアニメーションを設定
/* ナビゲーションメニュー:(開いた状態) */
.open .nav {
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
color: #ffffff;
}
.nav ul {
margin-bottom: 10vh;
list-style: none;
}
.nav li:not(:last-child) {
margin-bottom: 20px;
}
- ナビゲーションを表示している画面の設定
- .open .navクラスでテキストを表示している
- ulでリストの「・」を削除し、テキストの位置を調整
- li:not(:last-child) でテキストの幅を調整している
JavaScript
function navFunc() {
document.querySelector('html').classList.toggle('open')
}
- htmlタグにopenクラスが無ければ追加し、あれば削除する処理
参考資料
↓ スクリーンリーダーの説明
Discussion