にしし ふぁくとりー(西村文宏 個人サイト)

"CSS Tips Factory" : Presented by Nishishi via WordPress.

hover疑似クラスで(マウスが載った際に)リンク画像を切り替える [イメージ,リンク,配置]

画像リンク(=リンクになっている画像)の上にマウスポインタを載せたときに、マウスポインタが載っている間だけ別の画像に差し替えるデザインがよくあります。そのような「マウスが載ったときに画像を切り替える」機能は、JavaScriptなどのスクリプトを活用することなく、スタイルシートだけで作れます。

「要素の上にマウスポインタが載ったとき」の装飾は、hover疑似クラスを使うことで指定できます。つまり、hover疑似クラスを使って画像を切り替えれば良いわけです。ただ、表示する画像ファイルそのものを切り替えるよりも、背景画像の表示領域をずらすことで「画像が切り替わったような効果を出す」テクニックの方が、(切り替え先の画像の読み込みを待たずに済む分)動作が高速です。

hover疑似クラスを使って、マウスが載った際にリンク画像を切り替える方法

方法はとても簡単で、具体的には以下の通りです。

  1. まず準備として「最初に表示するリンク画像」と「マウスが載ったとき用のリンク画像」の2枚の画像が必要ですが、2つの独立した画像ファイルの形にはせず、横方向に結合した「1枚の大きな画像」として作成しておきます。
  2. リンクの背景画像としては、画像の片側半分だけが表示されるようにスタイルシートを書いておきます。
  3. hover疑似クラスを使って、背景画像の表示領域をスライドさせれば、画像が切り替わったような効果を出せます。

例えば、以下のような画像を用意しておきます。これは、2つの写真を1つの画像ファイルとして合成したものです。
hoverでスライドさせるリンク用画像サンプル

そして、次のようなHTMLを書きます。これは非常にシンプルですね。ただリンクが1つあるだけです。後からスタイルシートで装飾を加えるために、class属性を加えています。

<a href="/" class="photolink">写真コーナーへ</a>

上記で指定した「写真コーナーへ」というリンク文字は、CSSを解釈しない環境(音声読み上げ時など)で代替文字として機能します。

そして、CSSソースを以下のように記述します。

a.photolink {
   display: block;
   width: 120px;         /* 画像1枚分の横幅 */
   height: 100px;        /* 画像1枚分の高さ */
   text-indent: -1000px; /* 文字を見えなくする */
   background-image: url("linkphoto.jpg"); /* 画像ファイル名 */
}

上記のCSSソースで、先のHTMLソースで作ったリンクが「画像リンク」になります。その際、表示される画像は、先ほどの「2枚の写真が1つに合成された画像」の左側半分(海の写真)です。

続けて、マウスが載ったときの動作(hover疑似クラス)をCSSで記述します。

a.photolink:hover {
   background-position: top right; /* 背景画像の表示開始基準を右上に変更 */
}

これで完成です。
上記のCSSソースによって、以下のような表示(動作)になります。

  • 通常のリンク画像は、背景画像の左側半分が表示され、
  • マウスが載った際のリンク画像は、背景画像の右側半分が表示される。

リンクの上にマウスポインタが載ったときには、背景画像の表示開始位置が(デフォルトの位置である「左上」ではなく)「右上」に変わります。それによって、「2枚の写真が1つに合成された画像」の右側半分(山の写真)が表示されることになります。

上記のHTMLとCSSソースを実際に表示させてみると、以下のように見えます。

写真コーナーへ※この画像の上にマウスを載せてみて下さい。

画像の上にマウスを載せてみると、表示される画像が切り替わった効果が得られるはずです。(実際には、背景画像がスライドして右側半分が表示されるようになっただけです。)

JavaScriptなどを駆使して切り替えるよりもシンプルです。しかも、切り替え先の画像を改めて読み込む必要がないので、切り替え処理も一瞬で行われるメリットがあります。

複数個のリンク画像を横方向に並べたい場合は

先のCSSソースだと、リンク画像を複数個連続で記述しても横方向には並びません。なぜなら、displayプロパティに値「block」を指定してブロックレベル化しているためです。こうしないと高さ(height)の指定が効かないので、画像の高さに合わないからです。

もし、このリンクを横方向に複数個並べて配置したい場合は、displayプロパティの値を「block」ではなく「inline-block」にすると良いでしょう。以下のような感じで記述します。

a.photolink {
   display: inline-block;  /* 横に並ぶようにする */
   width: 120px;         /* 画像1枚分の横幅 */
   height: 100px;        /* 画像1枚分の高さ */
   text-indent: -1000px; /* 文字を見えなくする */
   background-image: url("linkphoto.jpg"); /* 画像ファイル名 */
}

もしくは値を「block」にしたまま、下記のようにfloatプロパティを加えても良いですが。この方法だと、回り込みの解除が必要になるので、後が面倒な気がします。

a.photolink {
   display: block;
   width: 120px;         /* 画像1枚分の横幅 */
   height: 100px;        /* 画像1枚分の高さ */
   text-indent: -1000px; /* 文字を見えなくする */
   background-image: url("linkphoto.jpg"); /* 画像ファイル名 */
   float: left;   /* 左に寄せて後続を回り込ませる */
}

表示例(inline-blockを使った場合)は以下の通りです。

写真コーナー1へ 写真コーナー2へ 写真コーナー3へ ※これらの画像の上にマウスを載せてみて下さい。

上記では、3つのリンク画像が横に並んでいるはずです。(描画領域の幅が足りる限りは。)

補足:背景画像の表示開始位置

今回ご紹介したCSSソースでは、background-positionプロパティを使っての背景画像の表示開始位置は、hover疑似クラス側にしか記述しませんでした。背景画像の表示開始位置(background-positionプロパティの値)はデフォルトで「左上(=top left)」なので上記サンプルでは書きませんでした。省略していても問題ないはずです。しかし、不安であればノーマルなa要素側の装飾にも「background-position: top left;」の記述を加えて、「左上」から描画されるよう明示しても良いでしょう。

補足:そもそもtext-indentにマイナスを指定するのは好ましくはないかも

ここでは、text-indentプロパティに充分大きなマイナスの値を指定することで、本来表示されるはずのテキスト(文字)を見えなくしています。しかし、この方法はあまりスマートではありません。

例えば、「リンクそのものを画像にする(=a要素の中にimg要素を使って画像を表示する)」ようにしておき、「hover時に見せたい画像をCSSで背景画像として指定」しておき、「hover時にはopacityプロパティを使ってimg要素を透明にする」といった方法でも良さそうです。その方法は、別の機会に解説したいと思います。

《2016/02/03 16:06 改訂》
《2007年5月15日 13:21 初版公開》

スタイルシートTipsの主要なカテゴリ

現在、以下のカテゴリに区分してスタイルシートに関するTIPSを公開しています。カッコ内の数字は、該当する記事の件数です。

▲各カテゴリ毎に、TIPSのタイトルと概要を一覧できます。ぜひ、いろいろ覗いてみて下さい!

著者紹介

Twitter:にしし/西村文宏
にしし/西村文宏 on facebook にしし/西村文宏 on mixi にしし/西村文宏 on Google+

関連書籍・関連ソフトなど

--- 当サイト内を検索 ---