ドロワーメニュー
- JavaScriptでイベント作成(jQueryを利用しない場合)
ドロワーメニューの考え方
- PCサイズで横並びのナビゲーションメニュー
- スマートフォンサイズでは、初期では「ハンバーガーメニュー」が見えていて、ナビゲーションメニューは非表示になっている
- 「ハンバーガーメニュー」がクリックされると、横からスライドしてナビゲーションメニューが表示される
- その時、「ハンバーガーメニュー」の形もわかりやすく変更される
作り方
1. ロゴ(h1)とnavの横並び
- 親要素に「display: flex;」
- 「h1」に「margin-right: auto;」
メディアクエリ内でナビゲーションメニューを縦並び
- この段階では、ナビゲーションメニューがスマートフォンの画面にいっぱいに表示されている状態
@media screen and (max-width: 767px) { /* ---------- gnav ---------- */ .gnav { position: fixed; left: 0; top: 0; width: 100vw; height: 100%; background-color: rgba(18, 112, 188, 1.0); color: white; transition: right 0.3s ease; z-index: 800; } .gnav ul { display: grid; place-content: center; height: 100vh; } .gnav ul li { margin: 15px 0; line-height: 1.4; } .gnav ul li a { color: #fff; text-decoration: none; } }
クリックイベントを作成
- jQueryは不要
- ボタンがクリックされたとき、「html(root要素)」に対してクラス名「open」を付与
document.querySelector('#navButton').addEventListener('click', () => { document.querySelector('html').classList.toggle('open'); });
クラス名「open」が付与されたときのトグルボタンのアニメーション
/* イベントにより.openが付与されたときのアニメーション */ .open .nav_button span:nth-child(1) { transform: translate(0, 8px) rotate(45deg); background: #444; } .open .nav_button span:nth-child(2) { transform: scaleX(0); opacity: 0; } .open .nav_button span:nth-child(3) { transform: translate(0, -10px) rotate(-45deg); background: #444; }
全体の記述例
style.css
@charset "UTF-8"; /* --------------------------------------- reset --------------------------------------- */ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } ul { list-style: none; } a { color: inherit; text-decoration: none; } img { max-width: 100%; vertical-align: bottom; } html { font-size: 100%; scroll-behavior: smooth; } /* --------------------------------------- body --------------------------------------- */ body { display: grid; grid-template-rows: auto 1fr auto; min-height: 100vh; background-color: #fff; color: #333; font-size: 1.0rem; font-family: Arial, sans-serif; line-height: 1.0; } /* --------------------------------------- header --------------------------------------- */ .header { position: relative; color: #444; } .header > .container { padding: 9px 0; } .header h1 { font-size: 1.75rem; } @media screen and (min-width: 768px) { .header > .container { display: flex; align-items: center; width: min(92%, 1240px); margin: auto; padding: 10px 0; } .header h1 { width: 200px; margin-right: auto; } } /* --------------------------------------- layout --------------------------------------- */ .container { width: min(94%, 1240px); margin: 0 auto; padding-top: 50px; } /* --------------------------------------- nav --------------------------------------- */ .nav_button { position: fixed; right: 0; top: 0; width: 60px; height: 60px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; background-color: #fff; z-index: 1000; } .nav_button span { width: 44px; height: 4px; background: #444; border-radius: 2px; transition: all 0.2s ease-in-out; } /* イベントにより.openが付与されたときのアニメーション */ .open .nav_button span:nth-child(1) { transform: translate(0, 13px) rotate(45deg); background: #444; } .open .nav_button span:nth-child(2) { transform: scaleX(0); opacity: 0; } .open .nav_button span:nth-child(3) { transform: translate(0, -14px) rotate(-45deg); background: #444; } /* ---------- gnav ---------- */ .gnav { position: fixed; right: -100vw; /* 初期位置は画面外 */ top: 0; width: 100vw; height: 100%; background-color: rgba(18, 112, 188, 1.0); color: #fff; transition: right 0.3s ease; z-index: 800; display: grid; place-content: center; } .gnav ul li { margin: 30px 0; line-height: 1.4; } .gnav ul li a { color: #fff; font-size: 2.0rem; text-decoration: none; } /* イベントにより.openが付与されたときの位置 */ .open .gnav { right: 0; } @media screen and (min-width: 768px) { .nav_button { display: none; } .gnav { position: static; width: auto; height: auto; background-color: #fff; right: 0; } .gnav > ul { display: flex; justify-content: center; align-items: center; } .gnav ul li { margin: 0; } .gnav ul li a { color: #333; font-size: 1.125rem; padding: 8px 20px; line-height: 1.2; white-space: nowrap; } .gnav li a { display: block; } .gnav li:first-of-type a { color: #333; line-height: 43.4px; } .gnav li a:hover, .gnav li a.current { background-color: #444; color: #fff; } } /* --------------------------------------- footer --------------------------------------- */ .footer { padding: 20px 0; background-color: #000; color: #fff; text-align: center; }
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>課題サイト</title> <link rel="stylesheet" href="css/style.css"> <script src="js/script.js" defer></script> </head> <body> <!-- header --> <header class="header"> <div class="container"> <h1><a href="index.html"><img src="img/title.svg" alt="課題サイト"></a></h1> <nav class="gnav" id="gnav"> <ul> <li><a href="#" class="current">Web Site</a></li> <li><a href="jsjq.html">JavaScript<br>jQuery</a></li> <li><a href="psai.html">Photoshop<br>Illustrator</a></li> <li><a href="php.html">PHP<br>WordPress</a></li> </ul> </nav> <div class="nav_button" id="navButton"> <span></span> <span></span> <span></span> </div><!-- /.nav_button --> </div><!-- /.container --> </header> <!-- /header --> <!-- main --> <main class="main"> </main> <!-- /main --> <!-- footer --> <footer class="footer"> <p id="update">更新日:2024年11月21日</p> </footer> <!-- /footer --> </body> </html>
script.js
document.querySelector('#navButton').addEventListener('click', () => { document.querySelector('html').classList.toggle('open'); });