画像置換を用いた横型メニュー rev.3

(X)HTML 文書では文字列で書いておいて、ブラウザでの表示時には CSS により画像に置き換える手法――いわゆる画像置換を用いた横型のメニューのサンプルです。 rev.2 では IE8 beta2 用に特別な CSS を書いていましたが、IE8 製品版候補 1 の登場でその必要がなくなったため、該当 CSS を削除しました。

画像の置換方法ですが、置換を行う要素の ::before 擬似要素に、CSS の content プロパティで画像を設定するという方法をとっています。 要素の width、height を画像のサイズに合わせておくことで、元の文字は画像に押し出されて表示領域外に出て行きます。 画像が非表示設定の場合は押し出されずに文字が表示領域に残ります。

また、content プロパティを使えない Internet Explorer の 6 や 7 に対しては、list-style-image プロパティを利用した方法で対応しています。

Sample

画像置換を用いた横型メニューの表示サンプル (Opera 9.5)

実際に動くサンプルは コチラ にあります。

CSS オン、画像表示の環境なら大抵のブラウザで問題なく表示されると思います。 なお、一番右端は、画像が読み込めなかった場合の表示のサンプルとしてわざと存在しない画像ファイルを指定しています。

Source

HTML Code

サンプルの HTML コードです。

ul 要素の下に li 要素、さらにその下に a 要素、というシンプルな構成です。 各 a 要素を CSS から参照するためにクラス名の設定を行っていますが、属性値による CSS セレクタが使えるブラウザが一般的になったら、href 属性の値で各 a 要素を参照する、という方法を採るといいかもしれません。 とりあえず現在は IE6 が居るからダメですけど(´・ω・`)

ir.htm のソースコード
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <title>画像置換を用いた横型メニューのサンプル</title>
    <link type="text/css" charset="UTF-8" rel="stylesheet" media="screen" href="ir.css" />
    <!--[if IE 6]><link type="text/css" charset="UTF-8" rel="stylesheet" media="screen" href="ir_ie67.css"><![endif]-->
    <!--[if IE 7]><link type="text/css" charset="UTF-8" rel="stylesheet" media="screen" href="ir_ie67.css"><![endif]-->
  </head>
  <body>
    
    <p>画像置換を用いた横型メニューのサンプルです。
      <br />解説ページは
      <a href="../horizontalMenu.htm" title="画像置換を用いた横型メニュー">コチラ</a>
      です。</p>
    
    <ul id="imageReplacing">
      <li class="home"><a href="../horizontalMenu.htm">HOME</a></li>
      <li class="about"><a href="../horizontalMenu.htm">このサイトについて</a></li>
      <li class="sample1"><a href="../horizontalMenu.htm">sample1</a></li>
      <li class="sample2"><a href="../horizontalMenu.htm">画像なし sample</a></li>
    </ul>
    
  </body>
</html>

CSS Code

サンプルの CSS コードです。

border や背景色の設定を行っているのでごちゃごちゃしてますが、重要な部分は強調している部分です。 それと各画像の URL の指定を行っている部分と。

ir.css のソースコード
@charset "UTF-8"; /* 文字コード宣言 */
@namespace "http://www.w3.org/1999/xhtml";

a {
  text-decoration: none;
}
* {
  background-repeat: no-repeat;
}

/*===== 画面表示用 =====*/
@media screen {
  
  ul#imageReplacing {
    overflow: hidden;
    list-style: none;
    width: 604px; height: 30px;
    padding: 0px; margin: 20px;
    font-size: 14px;
    border-style: solid none double solid;
    border-color: #46251A;
    border-width: 1px 0px 3px 1px;
    /*position: absolute; top: 300px; 絶対配置でも問題なし*/
  }
  
  #imageReplacing li {
    float: left; /* clear: left;*/
    overflow: hidden;
    width: 150px; height: 30px; /* 画像の大きさ */
    /*margin: 0px;
    padding: 0px;*/
    border-right: 1px solid #46251A;
    position: relative;
  }
  #imageReplacing li a {
    display: block;
    overflow: hidden;
    height: 100%; width: 100%;
    background-color: #FFF1CC;
  }
  #imageReplacing li a:hover, 
  #imageReplacing li a:focus, 
  #imageReplacing li a:active {
    background-color: #F4EFCA;
  }
  #imageReplacing li a::before {
    display: block;
    float: left;
    color: #333333;
  }
  /* IE6 に以下のプロパティが適用されるとうまく動かないため子選択セレクタ ">" で IE6 には
    認識されないようにする */
  #imageReplacing li>a:hover:before, 
  #imageReplacing li>a:focus:before, 
  #imageReplacing li>a:active:before {
    margin-left: -150px;
  }
  /* "home" ボタン設定 */
  #imageReplacing li.home a:before {
    content: url("ir_home.png");
  }
  /* "about" ボタン設定 */
  #imageReplacing li.about a:before {
    content: url("ir_about.png");
  }
  /* "sample1" ボタン設定 */
  #imageReplacing li.sample1 a:before {
    content: url("ir_sample1.png");
  }
  /* "sample2" ボタン設定 */
  #imageReplacing li.sample2 a:before {
    content: url("none.png");
  }
}

/*===== 印刷用 =====*/
@media print {
  ul#imageReplacing {
    overflow: hidden;
    width: 604px; height: 30px;
    padding: 0px; margin: 20px;
    font-size: 14px;
    border-style: solid none double solid;
    border-color: #46251A;
    border-width: 1px 0px 3px 1px;
    /*position: absolute; top: 300px; 絶対配置でも問題なし*/
  }
  #imageReplacing li {
    float: left;
    display: block;
    overflow: hidden;
    width: 150px; height: 30px; /* 画像の大きさ */
    border-right: 1px solid #46251A;
  }
  #imageReplacing li a {
    display: list-item;
    list-style: disc inside; /* none を設定すると画像も表示されなくなる. */
  }
  /* "home" ボタン設定 */
  #imageReplacing li.home a {
    list-style-image: url("ir_home.png");
  }
  /* "about" ボタン設定 */
  #imageReplacing li.about a {
    list-style-image: url("ir_about.png");
  }
  /* "sample1" ボタン設定 */
  #imageReplacing li.sample1 a {
    list-style-image: url("ir_sample1.png");
  }
  /* "sample2" ボタン設定 */
  #imageReplacing li.sample2 a {
    list-style-image: url("none.png");
  }
}

IE6IE7 は CSS の content プロパティに対応していないので、それなりに CSS を書く必要があります。 が、画像は共通で使用できるので、それほど手間にはならないでしょう。

ir_ie67.css のソースコード
@charset "UTF-8"; /* 文字コード宣言 */
@namespace "http://www.w3.org/1999/xhtml";

/*===== 画面表示用 =====*/
@media screen {
  #imageReplacing li a { /* IE 6, 7 用 */
    display: list-item;
    list-style: disc inside; /* none を設定すると画像も表示されなくなる. */
    vertical-align: bottom;
    line-height: 31px; /* 画像が非表示の場合の文字の位置調節. 画像の高さより 1px 大きめに設定 */
    margin-left: -300px;
    padding-left: 300px;
  }
  #imageReplacing li a:hover, 
  #imageReplacing li a:focus, 
  #imageReplacing li a:active { /* IE 6, 7 用 */
    background-position: -150px 0px;
  }

  #imageReplacing li.home a { /* IE 6, 7 用 */
    background-image: url("ir_home.png");
    list-style-image: url("ir_home.png");
  }

  #imageReplacing li.about a { /* IE 6, 7 用 */
    background-image: url("ir_about.png");
    list-style-image: url("ir_about.png");
  }

  #imageReplacing li.sample1 a { /* IE 6, 7 用 */
    background-image: url("ir_sample1.png");
    list-style-image: url("ir_sample1.png");
  }

  #imageReplacing li.sample2 a { /* IE 6, 7 用 */
    list-style-image: url("none.png");
    background-image: url("none.png");
  }
}

使用した画像

サンプルに使用した画像は以下です。

通常時に表示する画像と、ロールオーバーに使用する画像をまとめておいて、マウスオーバー時には負のマージンでずらすことでロールオーバーを実現しました。

ブラウザの対応状況

Firefox 3.5期待通りの動作
Firefox 3期待通りの動作
Firefox 2期待通りの動作
Opera 9.6期待通りの動作
Safari 4期待通りの動作
Safari 3期待通りの動作
IE8 期待通りの動作
IE7期待通りの動作
IE6期待通りの動作
IE5.5 このままでは期待通りには動作しない. IE5.5 用の CSS を書くことで、似たような動作をさせることが可能. ただし画像非表示の場合に何も表示されない. また、もともと画像置換を行わないような CSS を書くことも可能. 好みで選択することになります.
NetFront (PSP 搭載ブラウザ) 画像置換が行われない. 文字は表示され、通常通りリンクとして機能

モダンブラウザでは問題なく表示されます。 IE6 と IE7 も対策をしていますので一応期待通りの動作をします。

問題は IE5.5 ですね。 IE5.5 はもはやどうでもいい、と言うとあれですが、まあ IE5.5 でも画像を表示させたいなら適当に CSS を書けば一応対応はできると思います。

IE8 は beta2 では微妙な動作をしていましたが、製品版候補 1 では問題なく動作するようになっていました。 よかったよかった。

関連項目


'09.01.29 rev.3 を作成。 IE8 製品版候補 1 の登場に対応し、IE8 beta2 用の崩れ対応策を削除しました。
'09.07.16 IE 8、Firefox 3.5、Safari 4 の登場にあわせて微妙に修正。
'09.07.21 印刷時にちゃんと印刷できるように CSS を変更。