以前にも書いたことがあると思いますが、本当にCSSでの表現が多彩にできるようになり(というか、先人たちの知恵や工夫により表現できることを知ったというのが正解ですね)、Javascriptに頼ることないコーディングも可能になっていますよね。
もちろん、JSを活用することにより色々な動きを制御することは可能になりますし、それ以上にサーバーサイドやブラウザゲーム開発など、複雑なプログラミングをすることが出来ますよね。
ただ、webでのお手軽なギミックにおいてはなるべくシンプルなCSSにて処理したいなと考えるタイプだったりします。
今回はたびたび出てくるメニュー関連です。
ちょっと仕事で実装する機会があったのですが、それが「メニューがスッと降りてくるようにしてほしい」という依頼でした。
たぶん、「ドロップダウン的なメニューでマウスが乗ると下にサブメニューが展開する感じなんだろう」とあたりをつけて実装したやつです。
意外と簡単なcssで作れちゃうんですよ?
まずは元となるhtml
<html>
<head>
<meta charset=”utf-8″>
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
<meta >
<title>dropdown list</title>
<link rel=”stylesheet” href=””>
<style>
ul, li {margin: 0; padding: 0; list-style-type: none;}
li {width: 200px; text-align: center;}
.firstlist {display: flex;}
.upperlist:hover {background-color: #ccc;}
.secondlist li:hover {background-color: #eee;}
</style>
</head>
<body>
<h1>dropdown list</h1>
<ul class=”firstlist”>
<li class=”upperlist”>1
<ul class=”secondlist”>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</li>
<li class=”upperlist”>2
<ul class=”secondlist”>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</li>
<li class=”upperlist”>3
<ul class=”secondlist”>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</li>
<li class=”upperlist”>4
<ul class=”secondlist”>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</li>
</ul>
</body>
</html>
こんな感じです。
display:flex; で親のリスト(数字)を横並びにし、下に子リスト(アルファベットA~D)が並ぶ形に整えています。
ちなみにマウスカーソルが乗っかると(cssの:hoverの部分ですね)
こんな感じにバックグランドが灰色に反転するようにしてあります。
追加するCSSはこれだけ
先に追加するcssを書いてしまいますね。
.secondlist {position: absolute;}
.secondlist li {border: 1px solid black;}
.upperlist ul { opacity: 0; visibility: hidden; transition: .5s; top: 50%;}
.upperlist:hover ul { opacity: 1; visibility: visible; top: 100%;}
これだけで完成しちゃいます。ちょっと説明がややこしいかもですが…
・最初のポイントはposition。
upperlist部分にposition:relative;を指定します。親部分にこれを指定してあげることで、secondlistでposition:absolute;と絶対位置での配置を指定する際にその基準がupperlistに。
・次はtransitionです。
これ自体は時間変化の間隔を指定してあげるイメージです。
今回はコンマ5秒を指定。変化は通常状態がopacity: 0; visibility:hidden;と画面から消えて隠れている状態から、それぞれ1とvisibleと出てきている状態に変化させるという内容。そのキーとなるのが:hover でupperlist部分にマウスカーソルが乗ったらという条件になっているわけですね。
・最後にtopですが、これを50%から100%とすることで途中から下に降りてくるような動きを表現してくれています(※この辺りの数値は実際にいじってみると分かりやすいかも)。
あとはborderにて枠線を書いてあげたりしています。
動きがないのでわかりづらいかもですが、数字の部分にマウスをもっていくとスッとしたにメニューが下りてきて、アルファベット部分を選択する。。。みたいな動きになります。
まとめ
どうでしょうか? 自力のcssだけでも簡単に、そして少ない記述で実装できちゃうと思いませんか?
こういうのって、全部の動きや意味を理解して実装しなきゃいけないわけじゃないと思うんですが、それでも数値や諸々いじってみてカスタマイズというか動きを確認するのって大事だと思っています。
意外な発見があったりしますしね(*’ω’*)
というわけで何かの参考になれば幸いです。
最後に全コードを載せておきますので、コピペして試してみてください!
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta > <title>dropdown list</title> <link rel="stylesheet" href=""> <style> ul, li {margin: 0; padding: 0; list-style-type: none;} li {width: 200px; text-align: center;} .firstlist {display: flex;} .upperlist:hover {background-color: #ccc;} .secondlist li:hover {background-color: #eee;} .upperlist {position: relative; border: 1px solid lightgray;} .secondlist {position: absolute;} .secondlist li {border: 1px solid black;} .upperlist ul { opacity: 0; visibility: hidden; transition: .5s; top: 50%;} .upperlist:hover ul { opacity: 1; visibility: visible; top: 100%;} </style> </head> <body> <h1>dropdown list</h1> <ul class="firstlist"> <li class="upperlist">1 <ul class="secondlist"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> </ul> </li> <li class="upperlist">2 <ul class="secondlist"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> </ul> </li> <li class="upperlist">3 <ul class="secondlist"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> </ul> </li> <li class="upperlist">4 <ul class="secondlist"> <li>A</li> <li>B</li> <li>C</li> <li>D</li> </ul> </li> </ul> </body> </html>
コメント
シンプルでカスタマイズしやすいものを色々探していましたが
素晴らしい手法です。
ありがとうございます!
返信が遅くなりました。
参考になったようで良かったです~(*’ω’*)
はじめまして。
こちらなのですが、ドロップダウンの下階層メニューに行こうとすると下階層の2番目のメニューのところで、すぐにメニューが閉じてしまい、2番目のメニューがクリックできません。
上の例でいいますと、下階層のB以降がクリックできないということです。
原因がわかりましたら教えていただけないでしょうか。
どうぞよろしくお願いいたします。