img要素を使ったCSSロールオーバー+α

画像をリストで配置したグローバルナビゲーションにロールオーバーを設定する時の話。JavaScriptを使わずCSSだけで実現するロールオーバーはいくつかやり方があると思いますが、以下のパターンをよく使っています。

パターン1

完成イメージ

パターン1のスクリーンショット

デモ

img要素を使ったCSSロールオーバー+α デモ1

XHTML

<ul id="globalNav">
<li><a href="#"><img src="/img/nav1.gif" alt="ナビ1" /></a></li>
<li><a href="#"><img src="/img/nav2.gif" alt="ナビ2" /></a></li>
<li><a href="#"><img src="/img/nav3.gif" alt="ナビ3" /></a></li>
<li><a href="#"><img src="/img/nav4.gif" alt="ナビ4" /></a></li>
<li><a href="#"><img src="/img/nav5.gif" alt="ナビ5" /></a></li>
</ul>

CSS

#globalNav {
height: 30px; /* ナビ画像の高さ */
background: url(nav_active.gif) no-repeat 0 0;
overflow: hidden;
}
#globalNav li {
float: left;
width: 90px;
}
#globalNav li a {
display: block;
*zoom: 1; /* ie6,7 */
}
#globalNav li a:hover,
#globalNav li a:active {
text-indent: -9999px;
}

全てのナビがロールオーバーした状態の画像を用意し、#globalNavの背景に設定します。

パターン1 スライスを切る様子

li要素に明示的な幅指定を行っておき、その子であるa要素にdisplay:block;を設定。
a:hover時にtext-indent:-9999px;を設定することでimg要素を画面外に飛ばし、背景画像を見せることでロールオーバーさせています。

この手法の欠点は、各ボタンを格納するli要素に明示的に幅を指定しないと意図した表示にならないという点。仮に、各ボタンの横幅が異なっている場合、各li要素にclassとかidを振って別々の幅を指定してやらないといけないということになります。

パターン2

各ボタンの横幅が異なっているけれど、各li要素にclassやidを書きたくない場合・・・このシチュエーションって結構経験していて悩んでいたのですが、どうにか実現することができたのがこのパターンです。

XHTMLはパターン1と同じとして。

完成イメージ

パターン2のスクリーンショット

デモ

img要素を使ったCSSロールオーバー+α デモ2

XHTML

<ul id="globalNav">
<li><a href="#"><img src="nav_products.gif" alt="ナビ1" width="82" height="18" /></a></li>
<li><a href="#"><img src="nav_gallery.gif" alt="ナビ2" width="64" height="18" /></a></li>
<li><a href="#"><img src="nav_blog.gif" alt="ナビ3" width="39" height="18" /></a></li>
<li><a href="#"><img src="nav_about.gif" alt="ナビ4" width="56" height="18" /></a></li>
<li><a href="#"><img src="nav_contact.gif" alt="ナビ5" width="71" height="18" /></a></li>
</ul>

CSS

#globalNav {
height: 18px; /* ナビ画像の高さ */
overflow: hidden;
background: url(nav_active.gif) no-repeat 0 0;
font-size: 10px;
}
#globalNav li {
float: left;
margin-right: 20px;
*zoom: 1; /* ie6,7 */
}
#globalNav a {
display: -moz-inline-box;
display: inline-block;
*zoom: 1; /* ie6,7 */
vertical-align: bottom;
}
#globalNav a:hover,
#globalNav a:active {
padding-top: 9999px;
}

li要素には幅指定を行いません。そして、右のボタンとの余白をmargin-rightで設定しますが、全てのボタンでこれが同一になるように画像のスライスを調節します。一番右のmarginが領域を飛び出してしまうケースもあると思いますが、その辺は適当にうまくやります。

パターン2 スライスを切る様子

a要素はdisplay:inline-block;になるようにします。 そしてinline-blockなのでvertical-alignの調整も行っておきましょう。 inline-blockについてはCSS Nite in Ginza, Vol.27での小山田さんのセッション(のスライド)が参考になります。

また、img要素にwidth、height属性をそれぞれ明示的に指定をする必要があります。これはFirefox2で正しく表示するために必要です。

そしてa:hoverpadding-topに大きな値を指定して、含んでいるimg要素を追い出すようにしてやれば、完了です。追い出した部分を非表示にするために、#globalNavにheightの明示的な指定とoverflow:hidden;の指定が必要なのでお忘れなく。(この2つはfloat解除の意味合いもありますが)

Continue reading

XHTML+CSS プロが教える“本当の使い方”の一部を執筆しました

今更なご報告ではありますが、XHTML+CSS プロが教える“本当の使い方”のほんの一部(40ネタ中、2ネタ)を執筆させていただきました。同シリーズのJS本に引き続き今回も執筆をさせていただきました。

XHTML+CSS プロが教える“本当の使い方”

優れた著者陣の中で執筆をさせていただいたことは本当に恐縮であるとともに、直球なネタで行くのは自信がなかったので変化球的なネタを持ち込ませていただきました。結果的に本書に良い具合に彩りを添えることができたのではないかと思っています。

もし書店などでお見かけの際は、よろしければ手に取ってみてくださいませ。

XHTML+CSS プロが教える“本当の使い方”
MdN編集部
MdN
売り上げランキング: 4608