ドロップダウンメニューの作り方

ドロップダウンメニュー(別名プルダウンメニュー)は、メニューのタイトル部分をクリックするか、マウスポインターを置くことで、そこから下に垂れ下がるように表示されるメニューです。

CSS3のFlexboxを使用してのドロップダウンメニュー

CSS3のFlexboxを使用してのドロップダウンメニューの作成

メニューリストを作成する

まずはhtmlでメニューのリストを作成します。他のリストと一緒にならないよう、親のulタグにクラス名を作っておくといい。

<nav class="nav_test">
<ul class="menu_test">
<li><a href="リンク先URL">メニュー1</a>
  <ul>
  <li><a href="リンク先URL">子メニュー1</a>
  <li><a href="リンク先URL">子メニュー2</a>
  </ul>
<li><a href="リンク先URL">メニュー2</a>
<li><a href="リンク先URL">メニュー3</a>
</ul>
</nav>

cssでスタイル設定

1.横並びにする
css3のFlexboxを使い、横並びにし、リストマークとリストマークの余白、下線を消す。ついでに各項目の背景色とリンク選択時の背景色と余白も設定。

.nav_test ul {
    list-style-type: none;/* リストマークなし */
    padding: 0;/* リストマークの余白なし */
}
.menu_test {
    display: flex;/* 要素をFlexboxに定義 */
    justify-content: flex-start;/* 左寄せ配置 */
    text-align: center;/* テキストを中央寄せ */
}
.menu_test a {
    display: block;/* 要素をブロックに定義 */
    text-decoration: none;/* リンク下線なし */
    background-color: #FFEBCD;/* 背景色 */
    color: #696969;/* テキスト色 */
    padding: 10px;/* 余白 */
}
.menu_test a:hover {
    background-color: #DEB887;/* リンク選択時の背景色 */
}
justify-contentプロパティの値、flex-startをflex-endにすれば右寄せ、centerにすれば中央寄せになります。他にspace-betweenやspace-aroundもあります。
2.子メニュー以下を非表示にして、親メニューにマウスが来たときに表示するよう記述を追加。

.nav_test ul {
    list-style-type: none;/* リストマークなし */
    padding: 0;/* リストマークの余白なし */
}
.menu_test {
    display: flex;/* 要素をFlexboxに定義 */
    justify-content: flex-start;/* 左寄せ配置 */
    text-align: center;/* テキストを中央寄せ */
}
.menu_test li {
    position: relative;/* ボックスの配置基準 */
    z-index: 1;/* 前面に描画 */
    min-width: 130px;/* 親メニューの最小横幅 */
}
.menu_test a {
    display: block;/* 要素をブロックに定義 */
    text-decoration: none;/* リンク下線なし */
    background-color: #FFEBCD;/* 背景色 */
    color: #696969;/* テキスト色 */
    padding: 10px;/* 余白 */
}
.menu_test a:hover {
    background-color: #DEB887;/* リンク選択時の背景色 */
}
.menu_test li ul {/* 子メニュー */
    position: absolute;/* ボックスの配置基準 */
    top: 100%;/* 親メニュー上部からの表示位置 */
    left: 0;/* 親メニュー左端からの表示位置 */
    width: 100%;/* 親メニュー幅に合わせる */
}
.menu_test li ul li {
    visibility: hidden;/* 子メニューの非表示 */
    /* スライド表示させる場合は以下も */
    overflow: hidden;/* ボックスからはみ出た部分を非表示 */
    height: 0;
    transition-duration: 0.2s;/* 変化にかかる時間 */
}
.menu_test li:hover > ul > li {
    visibility: visible;/* 子メニューの表示 */
    /* スライド表示させる場合は以下も */
    overflow: visible;/* ボックスからはみ出た部分を表示 */
    height: 44px;/* 項目名が途切れて隠れないように注意 */
}
以上で完成。横幅指定がなければ子メニューの幅は親メニューの幅に準ずる。 スライド表示させた場合、heightを指定するので項目名が長いと途切れる可能性があります。

フェードイン表示ならheight指定はありません。フェードイン表示にする場合は.menu_test li ul liと.menu_test li:hover > ul > liの項目を削除して以下を追加

.menu_test li ul {
    visibility: hidden;
    opacity: 0;
   transition: .2s ease-in-out;
}
.menu_test li:hover > ul {
    visibility: visible;
    opacity: 1;
}

2階層下の孫メニューまで作る場合

htmlへの記述。

<nav class="nav_test">
<ul class="menu_test">
<li><a href="リンク先URL">メニュー1</a>
  <ul>
  <li><a href="リンク先URL">子メニュー1</a>
  <li><a href="リンク先URL">子メニュー2</a>
    <ul>
    <li><a href="リンク先URL">孫メニュー1</a>
    <li><a href="リンク先URL">孫メニュー2</a>
    </ul>
  </ul>
<li><a href="リンク先URL">メニュー2</a>
  <ul>
  <li><a href="リンク先URL">子メニュー3</a>
    <ul>
    <li><a href="リンク先URL">孫メニュー3</a>
    <li><a href="リンク先URL">孫メニュー4</a>
    </ul>
  <li><a href="リンク先URL">子メニュー4</a>
  </ul>
<li><a href="リンク先URL">メニュー3</a>
  <ul>
  <li><a href="リンク先URL">子メニュー5</a>
  <li><a href="リンク先URL">子メニュー6</a>
    <ul>
    <li><a href="リンク先URL">孫メニュー5</a>
    <li><a href="リンク先URL">孫メニュー6</a>
    </ul>
  </ul>
</ul>
</nav>
cssへ孫メニュー分追記。

.menu_test li ul li ul {
    top: 0;/* 子メニュー上部からの表示位置 */
    left: 100%;/* 子メニュー左端からの表示位置 */
}
.menu_test li:last-child ul li ul {/* 親メニュー最後のリストの孫表示は左側に表示 */
    left: -100%;
}
上記cssで孫よりも下の階層にも対応しているのでメニュー項目を増やす場合はhtmlへのリスト記述のみ。

おまけに

親メニューからのホバー時背景色の変更をキープする場合は
.menu_test a:hover {
background-color: #DEB887;/* リンク選択時の背景色 */
}
の部分を以下のように書き換える。
.menu_test > li:hover > a,
.menu_test > li:hover li:hover > a {
background-color: #DEB887;
}

また、親メニュー最後のリストから2番めのリストの孫表示も左側に表示したい場合は
.menu_test li:last-child ul li ul {
left: -100%;
}
の部分を以下のように書き換える。
.menu_test li:last-child ul li ul,
.menu_test li:nth-last-child(2) ul li ul {
left: -100%;
}

TOPへ
戻る