こんにちは、ヨロと申します。
今回作るのは、こんな感じのメニューバー。
今回はとても一般的な左上にロゴ、右上にハンバーガーボタン、
そして、それらの下にメニューボタンの一覧を並べて表示させるパターンのメニューバーの作り方の基本をご紹介。
HTMLとCSSでドロップダウンメニュー作成|レスポンシブ・子メニュー・孫メニューの作り方
という事で今回は、カーソルをメニューに合わせた時に、
別のカテゴリー(子要素)が表示されるようにしてみる。
HTML(index.html)
<!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="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<header>
<div class="header-wrapper">
<div class="title">
<div class="logo">ロゴ</div>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav>
<ul class="menus">
<li class="menu"><a href="#">ホーム</a></li>
<li class="menu"><a href="#">メニュー1</a></li>
<li class="menu"><a href="#">メニュー2</a>
<ul>
<li><a href="#">子メニュー1</a></li>
<li><a href="#">子メニュー2</a></li>
<li><a href="#">子メニュー3</a></li>
</ul>
</li>
<li class="menu"><a href="#">メニュー3</a></li>
</ul>
</nav>
</div>
</header>
<script src="js/script.js"></script>
</body>
</html>
// HTML(index.html)
<!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="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<header>
<div class="header-wrapper">
<div class="title">
<div class="logo">ロゴ</div>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav>
<ul class="menus">
<li class="menu"><a href="#">ホーム</a></li>
<li class="menu"><a href="#">メニュー1</a></li>
<li class="menu"><a href="#">メニュー2</a>
<ul>
<li><a href="#">子メニュー1</a></li>
<li><a href="#">子メニュー2</a></li>
<li><a href="#">子メニュー3</a></li>
</ul>
</li>
<li class="menu"><a href="#">メニュー3</a></li>
</ul>
</nav>
</div>
</header>
<script src="js/script.js"></script>
</body>
</html>
そして次に、CSSで見た目の部分を整える、
CSS(style.css)
* { box-sizing: border-box; }
ul, li {
padding: 0px;
margin: 0px;
list-style: none;
}
/* メニュー */
nav {
background-color: greenyellow;
}
.menus {
display: flex;
}
.menus li {
list-style: none;
}
.menu a { /* 文字色 */
display: block;
padding: 15px;
text-decoration: none;
}
.menu a:hover {
background: rgba(128, 128, 128, 0.2); /* グレーの薄さ0.2 文字色はそのまま */
}
.menu ul {
position: absolute;
display: none;
background-color: greenyellow; /* hover時に表示される子要素の色 */
z-index: 10;
}
.menus li:hover ul {
display: block; /* これがないと、hover時に表示されない */
}
そして、ロゴとハンバーガーボタンの部分に関してはこんな感じ。
// CSS(style.css) ロゴとハンバーガーボタン部分
.title {
display: flex;
height: 50px;
padding: 0px 10px;
}
.title div:nth-child(1) {
margin-right: auto;
}
.logo {
margin: auto 0; /* ここで上下中央に配置 */
}
/* ここでハンバーガー枠全体のサイズ */
.hamburger {
position: relative;
width: 20px;
height: 16px;
margin: auto 0; /* ここで上下中央に配置 */
}
/* 三本線 */
.hamburger span {
position: absolute;
left: 0;
width: 100%;
height: 2px;
background-color: #000;
z-index: 10;
}
/* 三本線の上の部分 */
.hamburger span:nth-of-type(1) {
top: 0;
}
/* 三本線の中心部分 */
.hamburger span:nth-of-type(2) {
top: 7px;
}
/* 三本線の下の部分 */
.hamburger span:nth-of-type(3) {
bottom: 0;
}
/* ハンバーガー三本線:棒の動きや傾き加減など */
.hamburger,
.hamburger span {
transition: all .3s; /* クリックしてからの動作時間 */
}
/* ここで数字を変えて傾きなどを調節 */
.hamburger.active span:nth-of-type(1) {
transform: translateY(10px) rotate(-45deg);
-webkit-transform: translateY(7px) rotate(-45deg);
}
.hamburger.active span:nth-of-type(2) {
opacity: 0;
}
.hamburger.active span:nth-of-type(3) {
transform: translateY(-12px) rotate(45deg);
-webkit-transform: translateY(-7px) rotate(45deg);
}
script.js
そして、ハンバーガーボタンがきちんと反応してくれるようにするには、
script.js:ハンバーガーボタンを動かす
$(function() {
$('.hamburger').click(function(){
$('.hamburger').toggleClass('active');
});
});
と書いて終わり。
これらのような、メニューの階層が少ないものだと、HTMLやCSSの記述も比較的シンプルで短く簡単。
ただ、もう少し階層の深いメニューボタンを作りたいといった場合は、
ヘッダー部分の中身を、もう少し細かく書いていく必要が出てくる。
ドロップダウンメニューの作成:階層が深い場合、子メニュー、孫メニューの作り方
深い階層のメニューバーというのは、こんな感じで、
通常のメニューに加え、子メニュー、孫メニュー、下手すると孫メニューまでもあるパターン。
今回は、これを試しに作っていく。
HTML(index.html)
<header>
<div class="header-wrapper">
<div class="title">
<div class="logo">ロゴ</div>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav>
<ul class="menu">
<li><a href="#">HOME</a></li>
<li><a href="#">メニュー1</i></a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー</a></li>
</ul>
</li>
<li><a href="#">メニュー2</a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー</a></li>
</ul>
</li>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">メニュー3</a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">ひ孫メニュー</a></li>
<li><a href="#">ひ孫メニュー</a></li>
<li><a href="#">ひ孫メニュー</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</header>
CSSの処理をせずに、HTMLだけだとこんな感じ。
そして、次にCSS
CSS(style.css)
* { box-sizing: border-box; }
a {
text-decoration: none;
}
ul, li {
padding: 0px;
margin: 0px;
list-style: none;
}
.title {
display: flex;
height: 50px;
padding: 0px 10px;
}
.title div:nth-child(1) { /* ここでハンバーガーボタンを指定 */
margin-right: auto;
}
.logo {
margin: auto 0; /* ここで上下中央に配置 */
}
/* ハンバーガーボタン:ここで全体のサイズ */
.hamburger {
position: relative;
width: 20px;
height: 16px;
top: 10px;
left: 10px;
}
/* 三本線 */
.hamburger span {
position: absolute;
left: 0;
width: 100%;
height: 2px;
background-color: #000;
z-index: 10;
}
/* 三本線の上の部分 */
.hamburger span:nth-of-type(1) {
top: 0;
}
/* 三本線の中心部分 */
.hamburger span:nth-of-type(2) {
top: 7px;
}
/* 三本線の下の部分 */
.hamburger span:nth-of-type(3) {
bottom: 0;
}
/* ハンバーガー三本線:棒の動きや傾き加減など */
.hamburger,
.hamburger span {
display: inline-block;
transition: all .4s; /* クリックしてからの動作時間 */
}
/* ここで数字を変えて傾きなどを調節 */
.hamburger.active span:nth-of-type(1) { /* 上の棒線 */
transform: translateY(10px) rotate(-45deg);
-webkit-transform: translateY(7px) rotate(-45deg);
}
.hamburger.active span:nth-of-type(2) { /* クリックしたら消える真ん中の棒線 */
opacity: 0;
}
.hamburger.active span:nth-of-type(3) { /* 下の棒線 */
transform: translateY(-12px) rotate(45deg);
-webkit-transform: translateY(-7px) rotate(45deg);
}
/* メニューの一覧 */
ul.menu {
background-color: greenyellow;
letter-spacing: -100px; /* inline-blockで要素を横並びにした時の隙間を無くす */
}
/* メイン */
ul.menu li {
position: relative;
display: inline-block; /* これが無いと、子と孫の位置がかなりずれる */
letter-spacing: normal; /* 上で指定したletter-spacingを元通りに */
}
ul.menu a {
display: block; /* リンクボタン全体をクリック出来るように */
padding: 15px; /* ここでメニューのサイズ */
}
ul.menu a:hover {
background: rgba(128, 128, 128, 0.2); /* グレーの薄さ0.2 文字色はそのまま */
}
/* サブメニュー(hover時) */
ul.menu li:hover > ul {
display: block; /* ここで表示(hover時) */
}
/* サブメニュー */
ul.menu ul {
display: none;
position: absolute;
}
/* サブメニュー以降 */
ul.menu ul li {
width: 160px; /* ここである程度の長さを指定しないと、文字が縦並びになる(px指定) */
background-color: greenyellow;
}
/* 孫メニュー以降の表示について */
ul.menu ul ul {
display: none;
position: absolute;
top: -1px; /* これがないと、項目の子メニューの真横に孫メニューが表示されない */
left: 100%; /* 親要素から、左から右に100%ずらす */
}
.fa-angle-double-right { /* Font Awesomeのアイコン */
font-size: 10px;
}
今回、>> の矢印アイコン部分には「Font Awesome」というサービスを使っていて、
Font Awesomeを読み込んで使う時のタグは、head内で、
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
を読み込ませればOK。
あとは、好みのアイコンを、Font Awesomeのサイトから探してくる。
ここまで書ければ、PC表示に関しては問題なし。
ドロップダウン メニューバー:レスポンシブ(スマートフォン)対応
PCで閲覧時は、ハンバーガーボタンを見えないようにして、メニューの一覧表示をする設定に、
スマホ表示時は、ハンバーガーボタンを表示し、メニューの一覧を隠す設定に。
スマートフォン仕様(レスポンシブ対応)にする場合は、CSSを再度別のファイルで読み込む、
今回はスマホで見た場合の設定を、responsive.cssに書いていくとして、
ファイルを読み込むタグは、
<link rel="stylesheet" href="css/responsive.css">
という事でまずは、ハンバーガーボタンを消す設定に、
style.css(PC閲覧時)
/* style.css:ハンバーガーボタンを隠す */
.hamburger,
.hamburger span {
/* ここに */
}
display: none; を追加して、ハンバーガーボタンを見えないようにする。
そして、スマホ側では、
responsive.css(レスポンシブ)
/* responsive.cssではハンバーガーボタンが見えるように */
.hamburger,
.hamburger span {
/* ここに追加 */
}
display: inline-block; を追加して、ハンバーガーボタンを表示する設定に。
ドロワーメニューで、メニュー一覧を表示する設定
今回はスマホで見る場合は、メニュー画面を画面の外に配置しておいて、
ハンバーガーボタンをクリックしたと同時に、メニューの一覧が画面上に表示される(画面の中に入ってくる)ように設定を書いてみる。
という事で、簡単なドロワーを作成。その場合まずは、
/* ここでメニューの一覧を画面の外へ配置 */
nav {
transform: translateX(100%);
}
transform: translateの意味合い
// transform: translate();
transform: translateX(100%); → 指定した要素を画面の右側に追いやる
transform: translateX(-100%); → 指定した要素を画面の左側に追いやる
transform: translateY(100%); → 指定した要素を画面の下に追いやる
transform: translateY(-100%); → 指定した要素を画面の上に追いやる
数字を指定する際は、%だけじゃなくvhなどを使用してもOK。
今回は、ハンバーガーボタンをクリックする度に、メニューの一覧が右側から現れるようにする設定。
script.jsに、
$(‘nav’).toggleClass(‘active’);を追加し、.hamburgerをクリックする度に、
navにも、activeというクラスをつけたり消したりといった指示を出す。
// script.jsでtoggleClassを使ってactiveクラスを足したり外したり
$(function() {
$('.hamburger').click(function(){
$('.hamburger').toggleClass('active');
$('nav').toggleClass('active');
});
});
.toggleClassを使う事によって、ボタンをクリックする度にその要素に「active」というクラス名を付与する事が出来る。
そして次に、CSS部分。
script.jsで、要素をクリックをする度に、.activeというクラスをつけたり外したりする設定を書いたので、
responsive.css内の要素に、activeクラスがついた時の処理を書く、
/* navにactiveクラスがついた時は、画面外にあるメニュー一覧を、元の位置に戻すように指示 */
nav.active {
transform: translateX(0%);
}
そうする事によって、ボタンをクリックする度に、ドロワーの開閉が出来るようになる。
ただ、今のままではクリックしてからメニューの一覧が、元の位置に戻るまでが早過ぎるので、
transition: all .3s; を付け加えて。アニメーションの速度の調節をする。
responsive.css
nav {
transform: translateX(100%); /* ここで要素を画面外に配置 */
transition: all .3s; /* 0.3秒かけて */
}
nav.active { /* アクティブ時 */
transform: translateX(0%); /* ここで要素を元の位置に */
transition: all .3s; /* 0.3秒かけて */
}
これでOK。
メニューバーの見た目の部分をレスポンシブ仕様(スマートフォン対応)に
今の状態だと、まだメニュー部分が横並びになっているので、
これらを縦並びにして見た目を軽く整える。その場合は、
responsive.css
ul.menu li {
display: inline-block;
}
の、display: inline-block;の部分を display: initial;で初期値に戻す。
ul.menu ul {
display: none;
position: absolute;
}
の中身も同じように、initialに、
ul.menu ul ul {
display: none;
position: absolute;
top: -1px;
left: 100%;
}
の中身も全て同じように、initialに、
そうすれば、全ての項目が縦並びになる、
あとの細かい調整は、またCSSで整えていけばOK。
そして最終的なソースコードはこんな感じ。
index.html
<!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="css/style.css">
<link rel="stylesheet" href="css/responsive.css">
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<header>
<div class="header-wrapper">
<div class="title">
<div class="logo">ロゴ</div>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav>
<ul class="menu">
<li><a href="#">HOME</a></li>
<li><a href="#">メニュー1</i></a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー</a></li>
</ul>
</li>
<li><a href="#">メニュー2</a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー</a></li>
</ul>
</li>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">メニュー3</a>
<ul>
<li><a href="#">子メニュー</a></li>
<li><a href="#">子メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">孫メニュー</a></li>
<li><a href="#">孫メニュー <i class="fas fa-angle-double-right"></i></a>
<ul>
<li><a href="#">ひ孫メニュー</a></li>
<li><a href="#">ひ孫メニュー</a></li>
<li><a href="#">ひ孫メニュー</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</header>
<script src="js/script.js"></script>
</body>
</html>
style.css
* { box-sizing: border-box; }
a {
text-decoration: none;
}
ul, li {
padding: 0px;
margin: 0px;
list-style: none;
}
.title {
display: flex;
height: 50px;
padding: 0px 10px;
}
.title div:nth-child(1) { /* ハンバーガーボタンを指定 */
margin-right: auto;
}
.logo {
margin: auto 0; /* ここで上下中央に配置 */
}
/* ハンバーガーボタン:ここで全体のサイズ */
.hamburger {
position: relative;
width: 20px;
height: 16px;
top: 10px;
left: 10px;
}
/* 三本線 */
.hamburger span {
position: absolute;
left: 0;
width: 100%;
height: 2px;
background-color: #000;
}
/* 三本線の上の部分 */
.hamburger span:nth-of-type(1) {
top: 0;
}
/* 三本線の中心部分 */
.hamburger span:nth-of-type(2) {
top: 7px;
}
/* 三本線の下の部分 */
.hamburger span:nth-of-type(3) {
bottom: 0;
}
/* ハンバーガー三本線:棒の動きや傾き加減など */
.hamburger,
.hamburger span {
display: inline-block;
transition: all .4s; /* クリックしてからの動作時間 */
z-index: 10;
}
/* ここで数字を変えて傾きなどを調節 */
.hamburger.active span:nth-of-type(1) { /* 上の棒線 */
transform: translateY(10px) rotate(-45deg);
-webkit-transform: translateY(7px) rotate(-45deg);
}
.hamburger.active span:nth-of-type(2) { /* クリックしたら消える真ん中の棒線 */
opacity: 0;
}
.hamburger.active span:nth-of-type(3) { /* 下の棒線 */
transform: translateY(-12px) rotate(45deg);
-webkit-transform: translateY(-7px) rotate(45deg);
}
/* メニューの一覧 */
ul.menu {
background-color: greenyellow;
letter-spacing: -100px; /* inline-blockで要素を横並びにした時の隙間を無くす */
}
/* メイン */
ul.menu li {
position: relative;
display: inline-block; /* これが無いと、子と孫の位置がかなりずれる */
letter-spacing: normal; /* 上で指定したletter-spacingを元通りに */
}
ul.menu a {
display: block; /* リンクボタン全体をクリック出来るように */
padding: 15px; /* ここでメニューのサイズ */
}
ul.menu a:hover {
background: rgba(128, 128, 128, 0.2); /* グレーの薄さ0.2 文字色はそのまま */
}
/* サブメニュー(hover時) */
ul.menu li:hover > ul {
display: block; /* ここで表示(hover時) */
}
/* サブメニュー */
ul.menu ul {
display: none;
position: absolute;
}
/* サブメニュー以降 */
ul.menu ul li {
width: 160px; /* ここである程度の長さを指定しないと、文字が縦並びになる(px指定) */
background-color: greenyellow;
}
/* 孫メニュー以降の表示について */
ul.menu ul ul {
display: none;
position: absolute;
top: -1px; /* これがないと、項目の子メニューの真横に孫メニューが表示されない */
left: 100%; /* 親要素から、左から右に100%ずらす */
}
.fa-angle-double-right { /* Font Awesomeのアイコン */
font-size: 10px;
}
responsive.css
@media (max-width: 1000px) {
.hamburger,
.hamburger span {
display: inline-block;
}
header {
position: relative;
}
/* メニュー部分 */
nav {
position: absolute;
top: 0;
width: 100vw;
transform: translateX(100%);
transition: all .3s;
}
/* メニュー部分:アクティブ時 */
nav.active {
transform: translateX(0%);
transition: all .3s;
}
nav {
transform: translateX(100%); /* ここで要素を画面外に配置 */
transition: all .3s;
}
nav.active { /* アクティブ時 */
transform: translateX(0%); /* ここで要素を元の位置に */
transition: all .3s;
}
ul.menu li {
display: initial;
}
ul.menu ul {
display: initial;
position: initial;
}
ul.menu ul ul {
display: initial;
position: initial;
top: initial;
left: initial;
}
}
・script.js
// script.js
$(function() {
$('.hamburger').click(function(){
$('.hamburger').toggleClass('active');
$('nav').toggleClass('active');
});
});
終わり。
ナビゲーション?グローバルメニュー?