cssだけでドロップダウンメニューを実装しようとして、色々ググったが、やり方がやたら複雑だったので、ここにメモしておきます。
そして、完成形のコード。
<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ファイル
/*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;
だと、要素を不可視にして、レイアウトから除外することができます。
注意したいのがdisplay: none;
にアニメーションをつける方法です。以下のようだと動きません。
/*通常は非表示*/
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 | キーフレームを利用したアニメーション |
/*アニメーション*/
@keyframes show{
from{
opacity: 0;
}
to{
opacity: 1;
}
}