CSSデザインノートでタグ「roll-over」が付けられているもの

CSS HappyLifeの平澤さんが新しいサイト「CSS HappyLife ZERO」をオープンされたのですが、そのメニュー部分がとても素敵だったので、参考に同じようなものを作ってみました。

ちなみに全くソースコードは拝見していませんので、同じようには作られてはいないと思います。

前回の記事「アクセシビリティの高いCSSロールオーバーメニュー」を参考にすれば、比較的簡単に作れそうです。

サンプル

動作確認

Firefox3.5.7、Google Chrome 3.0、Safari 4.0.4 for Windows XPです。IE6はhoverに対応していませんので、強調する効果は得られませんが、不具合なく表示する事はできます。Opera 10.10は正常に動作しません。なぜでしょう。「ul#menu li a」に「display:inline-block;」を追加するとちゃんと動作しました。

(X)HTMLコード

<ul id="menu">
   <li class="menu1"><a href="#" class="current"><img src="images/menu1.gif" alt="menu1" /></a></li>
   <li class="menu2"><a href="#"><img src="images/menu2.gif" alt="menu2" /></a></li>
   <li class="menu3"><a href="#"><img src="images/menu3.gif" alt="menu3" /></a></li>
   <li class="menu4"><a href="#"><img src="images/menu4.gif" alt="menu4" /></a></li>
   <li class="menu5"><a href="#"><img src="images/menu5.gif" alt="menu5" /></a></li>
</ul>

CSSコード

img {
   border:0;
}

ul#menu {
   float:left;
   margin:0;
   padding:0;
}

ul#menu:hover {
   background: url(images/bg_menu_hover.gif) no-repeat;
}

ul#menu li {
   float:left;
   margin:0;
   padding:0;
   list-style:none;
}

ul#menu li a {
   display:block;
   display:inline-block;
   width:100px;
   height:30px;
}

ul#menu li a:hover,
ul#menu li a.current {
   background-image:url(images/bg_menu_on.gif);
}

ul#menu li.menu1 a:hover,
ul#menu li.menu1 a.current {
   background-position:0 0;
}

ul#menu li.menu2 a:hover,
ul#menu li.menu2 a.current {
   background-position:-100px 0;
}

ul#menu li.menu3 a:hover,
ul#menu li.menu3 a.current {
   background-position:-200px 0;
}

ul#menu li.menu4 a:hover,
ul#menu li.menu4 a.current {
   background-position:-300px 0;
}

ul#menu li.menu5 a:hover,
ul#menu li.menu5 a.current {
   background-position:-400px 0;
}

ul#menu li img {
   position:relative;
   z-index:-1;
}

考え方としては、リスト(ul)の背景に目立たない用のリスト画像を指定し、特定のメニューにカーソルがあったときはそのメニューだけオンマウス用の画像に切り替え、他のメニューはリストの一番下に回りこませてることにより目立たない用のリスト画像が表示されるというわけです。

また、現在表示しているページのメニューも目立たせたい場合は、a要素にcurrentというクラス名をつけて、CSSのほうで個別にスタイルを指定するとよいと思います。

これまでロールオーバーメニューをCSSのみで作ろうとした場合、ちらつきが起こったり、画像をオフにしていたら見れなかったり、アクセシビリティが低くなってしまっていました。

しかし、ある程度これらを克服したCSSの書き方がありました!しかも非常にCSSソースコードがコンパクトになっています。

詳細は上記のブログを参考にしていただければと思います。

ポイントは画像の使い方でしょうか。 HTMLにて<img src="" alt="" />でマウスオーバー前の画像を表示、CSSにて背景画像でマウスオーバー時の画像を配置し、マウスオーバー時に表示する範囲をbackground-positionで設定しています。

これらの画像をz-indexでレイヤーの順番を変更にする事で、重なった画像がうまく表示されるという仕組みですね。

本来display:-9999pxで画面外にとばしてしまうところですが、うまく下のレイヤーに隠すとはなかなか面白いですね。

altでメニューの代替テキストを表示することで、画像がオフだったり読み込まれないときでも一応読めます。

また、最初からマウスオーバー時の画像を読み込んでいるので、マウスオーバー時にちらつきが発生することもありません。

難点は画像を作るのが面倒ってことですかね。メニュー個別に分かれたマウスオーバー前の画像と、マウスオーバー時の全てのメニューがくっついた画像を用意しないといけないのは、少し手間がかかりますね。その分、CSSソースコードはシンプルになるのですが。

ソースコードを引用させていただきます。

(X)HTMLコード

<ul id="menu">
   <li class="home"><a href="#"><img src="btn_home.png" alt="HOME" /></a></li>
   <li class="product" id="current"><a href="#"><img src="btn_product.png" alt="Product" /></a></li>
   <li class="about"><a href="#"><img src="btn_about.png" alt="About" /></a></li>
   <li class="blog"><a href="#"><img src="btn_blog.png" alt="Blog" /></a></li>
   <li class="contact"><a href="#"><img src="btn_contact.png" alt="Contact" /></a></li>
</ul>

CSSコード

#menu li {
	float: left;
	position: relative;
	z-index: 3;
}
#menu li a {
	background: url(menu.png) left top no-repeat;
	display: -moz-inline-box; /* Firefox2 用のスタイル */
	display: inline-block;
}
#menu li.product a { background-position: -135px 0; }
#menu li.about a { background-position: -255px 0; }
#menu li.blog a { background-position: -375px 0; }
#menu li.contact a { background-position: -495px 0; }
#menu li a:hover {
	position: static;
}
#menu li a:hover img ,
#menu li#current a img {
	position: relative;
	z-index: -1;
}

参考サイト

前回、CSSのみでロールオーバー効果のメニューを作る方法を紹介しましたが、カーソルを合わせたときの画像を、カーソルを合わせた瞬間に呼び出しているので、一瞬ですが読み込みのためちらつきが発生します。

それを回避するために、カーソルを合わせてたときに表示される画像を、ページが表示されたときにあらかじめ呼び出しておく方法があります。

使用する画像は以下のものです。メニューで使用する画像がすべてくっついています。

ロールオーバー用メニュー画像

それでは、サンプルとソースコードを見ていきましょう。

サンプル

(X)HTMLコード

<ul class="menu">
<li class="menu1"><a href="">メニュー1</a></li>
<li class="menu2"><a href="">メニュー2</a></li>
<li class="menu3"><a href="">メニュー3</a></li>
</ul>

CSSコード

ul.menu  {
   margin:0;
   padding:0;
}

ul.menu li {
   float:left;
   text-indent:-9999px;
   overflow:hidden;
   list-style:none;
}

ul.menu li a {
   display:block;
   width:150px;
   height:30px;
}

li.menu1 a {
   background:url(menu.gif) 0 0 no-repeat;
}

li.menu1 a:hover {
   background:url(menu.gif) 0 -30px no-repeat;
}

li.menu2 a {
   background:url(menu.gif) -150px 0 no-repeat;
}

li.menu2 a:hover {
   background:url(menu.gif) -150px -30px no-repeat;
}

li.menu3 a {
   background:url(menu.gif) -300px 0 no-repeat;
}

li.menu3 a:hover {
   background:url(menu.gif) -300px -30px no-repeat;
}


/* モダンブラウザ(Firefox Opera Safari)対策 */
ul.menu:after {
   content:".";
   display:block;
   height:0;
   clear:both;
   visibility:hidden;
   font-size:0;
}


/* Win版IE7とMac版IE5対策 */
ul.menu {
   display:inline-block;
}


/* Win版IE5および6対策 */
/* Hides from IE-mac \*/
* html ul.menu {
   height:1px;
}

ul.menu {
   display:block;
}
/* End hide from IE-mac */

backgroundプロパティで、表示する画像をずらしています。右や下にずらす場合はマイナス表示をしないといけないので注意です。

メニューを横並びにするのにfloatを使用している都合上、リスト以降の要素の回り込みを解除するためにclearfixハックを使っています。CSSソースコードの後半部分です。

3年くらい前(2006年頃)までは、メニューのロールオーバーにCSSを使うことがトレンドでした。しかしながら、テキストを画面外に飛ばし代替画像を表示する手法(画像置換法)のため、スパム行為に抵触するんじゃないかとの懸念から現在ではあまり使われなくなりました。

現在ではCSSの代わりにJavascriptを使用しているところが多いと思います。AJAX(エイジャックス:JavaScriptのHTTP通信機能を利用して非同期通信をするもの)の流行からJavascriptが脚光を浴び、「jQuery」や「Prototype」といったライブラリが登場し、多くのところからロールオーバー機能のついたライブラリが公開されています。

JavascriptもブラウザのほうでOFFにしていたら無効になるわけで、CSSもJavascriptも一長一短なところがあるのが現状です。

さて本題ですが、このロールオーバーの手法は、テキストにリンクがはってあることが条件になります。

サンプル

(X)HTMLコード

<ul class="menu">
<li class="menu1"><a href="">メニュー1</a></li>
<li class="menu2"><a href="">メニュー2</a></li>
<li class="menu3"><a href="">メニュー3</a></li>
</ul>

CSSコード

ul.menu {
   margin:0;
   padding:0;
}

ul.menu li {
   float:left;
   text-indent:-9999px;
   overflow:hidden;
   list-style:none;
}

ul.menu li a {
   display:block;
   width:150px;
   height:30px;
}

li.menu1 a:link {
   background-image:url(menu01.gif);
}

li.menu1 a:hover {
   background-image:url(menu01_on.gif);
}

li.menu2 a {
   background-image:url(menu02.gif);
}

li.menu2 a:hover {
   background-image:url(menu02_on.gif);
}

li.menu3 a {
   background-image:url(menu03.gif);
}

li.menu3 a:hover {
    background-image:url(menu03_on.gif) ;
}


/* モダンブラウザ(Firefox Opera Safari)対策 */
ul.menu:after {
   content:".";
   display:block;
   height:0;
   clear:both;
   visibility:hidden;
   font-size:0;
}

/* Win版IE7とMac版IE5対策 */
ul.menu {
   display:inline-block;
}

/* Win版IE5および6対策 */
/* Hides from IE-mac \*/
* html ul.menu {
   height:1px;
}

ul.menu {
   display:block;
}
/* End hide from IE-mac */

メニューを横並びにするのにfloatを使用している都合上、リスト以降の要素の回り込みを解除するためにclearfixハックを使っています。

CSSの読み込みの遅さを防ぐ

今回説明した方法だと、オンマウスにした瞬間ちらつきが発生します。その後は画像がキャッシュされるためちらつきは発生しなくなります。この問題を解決する手としては、オンとオフの画像をくっつけて作成し、部分的に呼び出す方法があるのですが、また別の機会に紹介します。

また、IE6などだとブラウザの設定によって毎回ページのキャッシュを取得するため、マウスを置いた際画像の読み込みが遅く、ちらついてしまう現象が起きます。この現象はFirefoxなどのほかのブラウザでは起こりません。

IE6対策に以下のコードをCSSファイルに記述します。

CSSコード


html {
  filter: expression(document.execCommand("BackgroundImageCache", 
  false, true));
}

これは、CSSファイル中にJavascriptコードを書いているのですが、IEの独自の書き方です。他のブラウザでは無視されるのでハックの必要はありません。背景画像をキャッシュしています。

Javascriptでメニューのロールオーバーをしたいときは

本サイトの趣向とは違いますが、Javascriptでメニューのロールオーバーができるライブラリをいくつか紹介します。

最近のブログ記事