jQueryで6行程度で、コピペでも実装できます。
コードは以下のようになります。
HTML
<div class="nav_wrapper">
<nav>
<ul class="primary_nav clearfix fade">
<li>
<span>フェードナビ</span>
<ul class="secondary_nav">
<li>
<a href="#">子ナビ1</a>
</li>
<li>
<a href="#">子ナビ1</a>
</li>
<li>
<a href="#">子ナビ1</a>
</li>
</ul>
</li>
<li>
<span>フェードナビ</span>
<ul class="secondary_nav">
<li>
<a href="#">子ナビ2</a>
</li>
<li>
<a href="#">子ナビ2</a>
</li>
<li>
<a href="#">子ナビ2</a>
</li>
</ul>
</li>
<li>
<span>フェードナビ</span>
<ul class="secondary_nav">
<li>
<a href="#">子ナビ3</a>
</li>
<li>
<a href="#">子ナビ3</a>
</li>
<li>
<a href="#">子ナビ3</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
CSS
.nav_wrapper {
width: 100%;
background-color: #f3f3f3;
margin-bottom: 150px;
}
.primary_nav {
width: 600px;
margin: 0 auto;
height: 60px;
}
.primary_nav > li {
width: 200px;
float: left;
position: relative;
}
.primary_nav > li span {
display: block;
width: 159px;
border-right: 1px solid #dfdfdf;
padding: 0 20px;
height: 60px;
font-size: 1.6rem;
line-height: 60px;
text-align: center;
transition: all 0.2s;
}
.primary_nav > li:first-child span {
width: 158px;
border-left: 1px solid #dfdfdf;
}
.primary_nav > li:hover span {
background-color: #dfdfdf;
}
.secondary_nav {
position: absolute;
left: 0;
top: 60px;
width: 250px;
display: none;
z-index: 1;
}
.secondary_nav li a {
display: block;
height: 30px;
padding: 0 20px;
font-size: 1.2rem;
line-height: 30px;
background-color: #fbf8f1;
border-bottom: 1px solid #e9e4d9;
transition: all 0.2s;
}
.secondary_nav li:last-child a {
border: none;
}
.secondary_nav li a:hover {
background-color: #feecc4;
}
jQuery
$(function() {
$(".fade > li").hover(
function() {
$(this)
.find(".secondary_nav")
.stop(true)
.fadeIn(500);
},
function() {
$(this)
.find(".secondary_nav")
.fadeOut(500);
}
);
});
HTMLについての解説
ナビゲーションの中にサブナビゲーションが入っているのでulタグを入れ子にしています。それ以外、特段変なHTMLにはしていません。第1階層のリストにspanが入っているのはデザイン上のものなので必須ではありません。
CSSについての解説
装飾的な内容の解説は省いて、構造について説明します。また、リセットCSSは各自適当に当てて下さい。
第1階層のliタグにはfloat: left
を掛けて、横幅を200px
、高さを60px
で決めてます。この横幅などに関しては中に入るテキストなどで変わって来るでしょう。また、position: relative
を第2階層をabsolute
にするために指定しています。
第2階層はposition: absolute
を指定していますが、これは第2階層が親よりも横幅が長くなった時に位置をずらしたり、第1階層との位置関係を調整するのに何かと便利なので入れています。なので、なくても問題はありません。当然のことながら、最初から見えていてはいけないので、display: none
で非表示にしています。
jQueryについての解説
1.フェードバージョン
$(function() {
...
});
は言わずもがなドキュメントの読み込みが終わったら実行してね、というjQueryの基本的な関数です。
$(".fade > li").hover(...);
でfadeクラスの子要素のliタグ(ここの場合は第1階層のliタグ)にホバーしたら...の内容を実行してね、というイベントです。今回はhover()
は第1引数と第2引数に関数を渡しています。第1引数はマウスがホバーした時、第2引数はマウスが離れた時の処理になります。hover
メソッドは引数1つでホバー時・離れた時の挙動を記述することもできますが、それぞれの挙動を少し分けるために今回は2つ引数を渡しています。
第1引数
function () {
$(this)
.find(".secondary_nav")
.stop(true)
.fadeIn(500);
}
thisはホバーした要素、つまり第1階層のli
を表し、find
メソッドで子要素でsecondary_navというクラスの要素を見つけます。さらにstop
メソッドでアニメーションを止め、fadeIn
メソッドで500ミリ秒でふわっと表示されるようにしています。なぜstop
メソッドを使うのかは後述します。
第2引数
function(){
$(this)
.find(".secondary_nav")
.fadeOut(500);
};
第2引数も第1引数と同じような感じですが、stop
メソッドがないのと、fadeIn
がfadeOut
になっています。動作としても第1引数との逆でマウスが離れると500ミリ秒でフェードアウトします。
.stop(true)
第1引数にいれたstop
メソッドですが、これがないと、連続でホバーした際に、アニメーションがホバーした回数だけ繰り返されてしまいます。それを止めるためにstop
メソッドを挿入しています。
stop
メソッドには2つの引数(真偽値)を渡せますが、ストップする挙動に違いがあります。stop(true,true)
でも問題ありませんが、その挙動に関しては好みの問題かなと思います。(スライドのような単純な動きではなく、複雑なアニメーションをする時は使い分ける必要があるかと思います)。
stop
メソッドの挙動の違いについては以下のページに詳しく書かれています。
jQuery.stopのjumpToEnd引数が便利すぎてやばい(JavaScript Advent Calendar 2010 5日目)
2.スライドバージョン
スライドバージョンもフェードバージョンとほとんど同じで、fadeIn
, fadeOut
をそれぞれslideDown
, slideUp
に書き換えるだけです。
$(function() {
$(".slide > li").hover(
function() {
$(this)
.find(".secondary_nav")
.stop(true)
.slideDown(500);
},
function() {
$(this)
.find(".secondary_nav")
.slideUp(500);
}
);
});
jQueryでやる利点
ドロップダウンメニューはCSSのみで作るやり方もありますが、jQueryでやる利点は約6行追加するだけで良いこと、表現を変えたくなったらすぐ変えられる点です。もし、フェードからスライドに変えたくなってもfadeIn
をslideDown
に変えればすぐ反映できます。また、動きをCSSから分離できるので、デザイン上のCSSとあまり干渉しない点もあります。
jQueryでやると簡単に表現できることもあるので、試してはいかがでしょうか?