CSSで画像のロールオーバー
画像の上にカーソルを載せると画像がロールオーバーして変化するアレ。
javascriptのonMouseoverイベント使うよりもCSS使ったほうが手っ取り早くて簡単に再現できる。
ソースも綺麗になるしね!
CSSで画像をロールオーバーさせるには:hover擬似要素を使って、普段は通常時の背景画像を表示させマウスカーソルが画像に重なったときロールオーバー時の画像をスライドして表示させる。
使用する(X)HTMLソース
<ul> <li><a href="#">項目1</a></li> <li><a href="#">項目2</a></li> <li><a href="#">項目3</a></li> <li><a href="#">項目4</a></li> <li><a href="#">項目5</a></li> </ul>
画像は1枚に纏める
使う画像は縦:50px、横:500pxのコレ
ロールオーバー前と後の画像をバラバラに用意するとファイル数が多くなるし、ロールオーバーさせた時に画像がチラつくようになるので画像は1枚に纏める。
上半分が通常時に表示させる部分、下半分がロールオーバー時に表示させる部分になる。
:hover擬似要素で画像をずらす
a要素に:hover擬似要素をつけて通常時は画像の上半分を表示させ、カーソルが乗っかったときにロールオーバーで画像をスライドさせて下半分を表示させる。
サンプル1
(X)HTML
<ul> <li class="c1"><a href="#">項目1</a></li> <li class="c2"><a href="#">項目2</a></li> <li class="c3"><a href="#">項目3</a></li> <li class="c4"><a href="#">項目4</a></li> <li class="c5"><a href="#">項目5</a></li> </ul>
各li要素にid/classをつける。
コレは背景画像の表示を開始させる位置を各項目で別々に設定するため。
今は適当なclass振ってあるけど実際は各項目に関連した分かりやすいid/classを振るといい。
CSS
ul#sample1 { background-image: url(img/design005.gif); /*通常時の背景画像指定*/ background-repeat: no-repeat; background-position: left top; /*通常時の背景画像表示開始位置*/ width: 500px; height: 25px; margin: 0; padding: 0; } ul#sample1 li { width: 100px; height: 25px; padding: 0; margin: 0; float: left; /*横並び*/ list-style: none; } ul#sample1 li a { text-decoration: none; width: 100px; height: 25px; padding: 0; margin: 0; display: block; /*ブロック要素化*/ } /*----------画像のスライド----------*/ ul#sample1 li.c1 a:hover { background-image: url(img/design005.gif); background-repeat: no-repeat; background-position: left -25px; /*横位置は変えず下に25pxスライド*/ } ul#sample1 li.c2 a:hover { background-image: url(img/design005.gif); background-repeat: no-repeat; background-position: -100px -25px; /*左に100px、上に25pxスライド*/ } ul#sample1 li.c3 a:hover { background-image: url(img/design005.gif); background-repeat: no-repeat; background-position: -200px -25px; /*左に200px、上に25pxスライド*/ } ul#sample1 li.c4 a:hover { background-image: url(img/design005.gif); background-repeat: no-repeat; background-position: -300px -25px; /*左に300px、上に25pxスライド*/ } ul#sample1 li.c5 a:hover { background-image: url(img/design005.gif); background-repeat: no-repeat; background-position: -400px -25px; /*左に400px、上に25pxスライド*/ }
通常時の背景画像はul要素に指定。
このほうがa要素に個別指定するよりcssのソース量を減らせる。
項目と項目の間を空けたい場合はa要素に個別指定するほうがいい。
a要素はインライン要素なのでそのままだとwidthもheightも指定できず、背景画像も途切れてしまうのでdisplay:blockをかましてブロック要素化する。
widthとheightはロールオーバーさせたい画像の大きさを指定。
項目1つのサイズはwidth:100px、height:25pxなので項目ごとに背景画像を左に100pxスライドし、通常時の項目1〜5の背景画像を表示させる。
例えば項目2なら背景画像を項目1つ分左にスライドすればいいので、横の表示開始位置は-100pxを指定すればいい。
ロールオーバー時は、:hover擬似要素でカーソルが重なったときに画像の表示位置を下に25pxずらして表示させる。
これで画像が切り替わったように見えるようになる。
テキストを飛ばす(text-indent)
画像のロールオーバーが出来たら次はテキストを消し飛ばす。
テキストを消し飛ばすにはtext-indentを使う。
サンプル2
CSS(修正部分)
ul#sample2 li { width: 100px; height: 25px; padding: 0; margin: 0; float: left; overflow: hidden; /*Firefox1.5以上で表示される余分な枠の消去*/ list-style: none; } ul#sample2 li a { text-indent: -9999px; /*テキストを-9999ピクセルインデントさせる*/ text-decoration: none; width: 100px; height: 25px; padding: 0; margin: 0; display: block; }
a要素にtext-indent:-9999pxをかましてテキストを左に-9999pxインデントさせる。
コレで各項目からテキストが消える。
消えると言っても本当に消えているのではなく、この場合は飛ばしているだけ。
なのでインデントさせる値が少ないとデュアルモニタ使った時なんか変な所にテキストが表示される事がある。
左詰されたページなら無問題だけど、センタリングしてるサイトは注意が要る。
また、Firefox1.5以上では設定したリンクをクリックするとインデントさせた方向に枠が表示される。
この枠を消すには、li要素の部分から外にはみ出たものは表示させないようにoverflow:hiddenを指定してやればいい。
テキストをインデントして飛ばす方法にはデメリットがある。
ブラウザの画像表示をOFFにすると何も表示されない状態になる。
CSSをOFFにするだけなら指定した背景画像が消える代わりに、インデントしたテキストが元に戻るので情報が伝わる。
画像表示をOFFにした場合は背景画像が消えて、テキストがインデントされたままになるのでそこに何があってどうなっているのか分からなくなってしまう。
IE5ではwidthと同時にtext-indentをかますと、テキストだけでなくてリンク領域と背景画像も一緒にずれるバグ有。
paddingでテキストの位置を調整
画像OFF環境でも情報伝えたい!IE5にも対応させたい!という人はtext-indentではなくpaddingを使ってテキストをずらすと幸せになれるかもしれない。
画像がOFFの状態でもメニューリストだとわかる様にテキストを外に飛ばさず背景画像と一緒に表示させる。
サンプル3
CSS
ul#sample3 { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: 0 0; width: 120px; height: 125px; margin: 0; padding: 0; } ul#sample3 li { width: 120px; height: 25px; padding: 0; margin: 0; overflow: hidden; /*li要素からはみ出した部分を非表示*/ list-style: none; } ul#sample3 li a { text-align: right; /*テキストを右詰*/ text-decoration: none; line-height: 25px; /*テキスト縦の位置調整*/ height: 25px; padding-right: 5px; /*テキスト横の位置調整*/ margin: 0; display: block; } /*----------画像のスライド----------*/ ul#sample3 li.c1 a:hover { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: -120px top; /*左に120pxスライド*/ } ul#sample3 li.c2 a:hover { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: -120px -25px; /*左に120px、上に25pxスライド*/ } ul#sample3 li.c3 a:hover { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: -120px -50px; /*左に120px、上に50pxスライド*/ } ul#sample3 li.c4 a:hover { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: -120px -75px; /*左に120px、上に75pxスライド*/ } ul#sample3 li.c5 a:hover { background-image: url(img/design005_03.gif); background-repeat: no-repeat; background-position: -120px -100px; /*左に120px、上に100pxスライド*/ }
a要素にpaddingつけてテキスト位置を調整。
今回は横にずらしただけなので、縦の位置はline-heightにheightと同じ値をつけて中間に持ってくる。
横の位置は、右詰なのでtext-align:rightをかましてpadding-right:5pxで右から5pxずらす。
widthはIE6のpaddingとwidthのバグを回避するために指定しない。
li要素にoverflow:hiddenをかまして、paddingでずらしてli要素からはみ出したa要素の部分を非表示にする。
この方法なら画像表示がOFFに設定されていてもテキストが残るので情報は伝わし、IE5の背景とリンク領域が一緒にインデントされるバグも回避できる。
テキストは画像とまんま同じにしないで、その項目に関連した単語や簡易的な説明にするといい。
サンプル3は縦並びだけどもちろん04実験場みたいに横並びも可能。