bokunonikki.net

cssだけでドロップダウンメニューを実装する

Wed Sep 18, 2019
Sun May 30, 2021
css

cssだけでドロップダウンメニューを実装しようとして、色々ググったが、やり方がやたら複雑だったので、ここにメモ。

ということで、まずは完成形。

そして、完成形のコード。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<ul class="basic-menu-list">
    <li class="basic-menu-item">
        <span href="#" class="basic-menu-link">ここがドロップダウンだよ</span>
        <ul class="child-menu">
            <li class="basic-menu-item"><a href="#">マイページ</a></li>
            <li class="basic-menu-item"><a href="#">ログイン</a></li>
            <li class="basic-menu-item"><a href="#">ログアウト</a></li>
        </ul>
    </li>
</ul>

cssファイル

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*drop-down-menu*/
ul {
    list-style: none;
}
a {
    text-decoration: none;
}
.basic-menu-list {
    border: 2px solid #f00;
}
/*通常は非表示*/
ul.child-menu {
    display: none;
    opacity: 0;
}
/*表示に切り替え*/
li.basic-menu-item:hover ul.child-menu {
    display: block;
    animation: show 2s;
    opacity: 1;

}
/*アニメーション*/
@keyframes show{
    from{
        opacity: 0;
    }
    to{
        opacity: 1;
    }
}

実装方法はシンプルで、通常はdisplay: none;で非表示にしておき、カーソルが重なったことをダイナミック擬似クラスである:hoverで検知して、display: block;で表示させるという方法。

display: none;ではなく、visibility: hiddenを使って非表示することもできますが、この場合だとレイアウト自体には要素が存在しているため、余計な空白ができてしまいます。display: none;だと、要素を不可視にして、レイアウトから除外することができます。

参考 developer.mozilla

注意したいのがdisplay: none;にアニメーションをつける方法です。以下のようだと動きません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/*通常は非表示*/
ul.child-menu {
    display: none;
    opacity: 0;
    transition: opacity 1s;
}
/*表示に切り替え*/
li.basic-menu-item:hover ul.child-menu {
    display: block;
    opacity: 1;
}

transitionプロパティを利用すると、始点と終点の2点間のアニメーションを作成することができますが、この場合だとdisplay: block;のタイミングでDOMが生成されるため、transitionプロパティの始点がない状態になります。

プロパティ 作成できるアニメーション
transition 始点と終点の2点間のアニメーション

という訳で、ここではanimationプロパティを使います。

プロパティ 作成できるアニメーション
animation キーフレームを利用したアニメーション
1
2
3
4
5
6
7
8
9
/*アニメーション*/
@keyframes show{
    from{
        opacity: 0;
    }
    to{
        opacity: 1;
    }
}

HTML5&CSS3デザイン 現場の新標準ガイド

See Also