解 説

マウスホバーでボタンなどの画像をフワッとクロスフェードさせたいという相談が多いので、何種類かのアプローチと失敗例などを書きました。

  1. CSS3でクロスフェードさせるサンプル
  2. jQueryでimgタグの画像をクロスフェードさせる(成功例)
  3. jQueryでCSSのbackground-mageをクロスフェードさせる(完成形)

CSSを使用した例

hover疑似クラス

マウスホバーはCSSでの設定が簡単です。
CSSでは:hover擬似クラスを使用します。この疑似クラスはa要素以外にも使用できます。
また、a要素に適用させる場合には、順番が大事です。
LVHA の順 です :link — :visited — :hover — :active
LOVE HEARTで覚えるとよいらしいです。(笑)

hover擬似クラスのサンプル
HTML

<div class="myimg"></div>

CSS
.myimg{
	background:url(mascot_rollout.png) no-repeat;
	width:137px;
	height:151px;
}
.myimg:hover{
	background:url(mascot_rollover.png) no-repeat;
}

CSS3 transitionでクロスフェード

上のサンプルでは単純に画像が入れ替わるのですが、これにフワッとクロスフェードをさせるにはCSS3のtransitionを使用します。

CSS3でクロスフェードさせるサンプル
IE8以下は当然使えないですが、firefoxもbackground-imageはアニメーションをしません。background-colorはアニメーションします。

.myimg{
	background-image:url(mascot_rollout.png);
	width:135px;
	height:150px;
	transition: background-image 1s;
}
.myimg:hover{
	background-image:url(mascot_rollover.png);
	transition: background-image 1s;
}

CSSによるクロスフェードで画像を入れ替える方法は簡単ですが、対応してないブラウザ対策が問題となります。

transitionプロパティ
マウスホバーしたときなど時間をかけて変化をさせることができます。

  1. アニメーションさせるCSSプロパティ
    背景色、文字のサイズなど、どのCSSプロパティを変化させるか
    transition-property: background;
  2. アニメーションしている時間の長さ
    Aの状態からBの状態に変化するのに何秒かけるか
    transition-duration:1s;
  3. アニメーションの速度変化(イージング)
    始めは素早く動くけれども、変化の終盤はゆっくり動くなど、変化する過程にどう抑揚を付けるか
    transition-timing-function:ease-out;
  4. アニメーションを開始するまでの時間
    マウスオーバなどのアクションがあってから、何秒経過してからアニメーションを始めるか
    transition-delay:0.5s;
  5. ショートハンドの書き方
    transition:background 1s ease-out 0.5s;

jQueryを使用した例

今度はimgタグで画像を置いてjQueryで入れ替える方法です。
jQueryを使うと簡単に属性を入れ替えることができます。イベントに応じて画像を変更するのはお手のものです。
attr()は指定した属性の値を取得したり、変更することのできるメソッドです。jQueryオブジェクトで使用することができます。引数が1つの場合は値を取り、2つの場合は値を変更します。

属性値の取得
$("CSSセレクタ").attr("属性")
属性値の変更
$("CSSセレクタ").attr("属性","属性値")

引数の数で役割の違うメソッドの解説はこちら

imgタグのsrc属性を入れ替える方法

imgのsrc属性をattr()を使用して変更し、画像を入れ替えることを試してみました。
imgタグの画像を入れ替えるサンプル
HTMLコード

<img src="mascot_rollout.png" alt="">

jQueryコード
$(function(){
   $('img').hover(function(){
        $(this).attr('src','mascot_rollover.png' );
   }, function(){
        $(this).attr('src', 'mascot_rollout.png');
   });
});

hoverイベントで、imgタグのsrc属性をjQueryで入れ替える仕組みです。
hoverイベントの書き方は以下のとおりです。

$("セレクター").hover(
    function (){
      マウスが重なったときの実行内容
    },
    function (){
      マウスが外れたときの実行内容
    }
);

汎用性を高めたimgタグのsrc属性を入れ替える方法

画像のファイル名を変更しても使えるように汎用性を高めたjQueryの書き方は次にようになります。

replaceを使用して汎用性を高めたサンプル

$(function(){
     $('img').hover(function(){
        $(this).attr('src', $(this).attr('src').replace('_rollout', '_rollover'));
     }, function(){
        $(this).attr('src', $(this).attr('src').replace('_rollover', '_rollout'));
     });
});

replace() はJavaScriptのメソッドです。

str.replace(“検索文字列”,”置換文字”);

fadeToを使用してクロスオーバーに挑戦

fadeToで一旦透明度を付けてattrで画像を入れ替えることを試してみた。
クロスオーバーさせるためにfadeToを使用したサンプル

$(function(){
     $("img").hover(function(){
	$(this).stop().fadeTo("slow", 0.5,function(){
	$(this).attr("src","mascot_rollover.png").stop().fadeTo("slow", 1);})
      },
     function(){
	$(this).stop().fadeTo("slow", 0.5,function(){
	$(this).attr("src","mascot_rollout.png").stop().fadeTo("slow", 1);})
      });
});

なんだか動きが不自然です。src属性を変更して画像を入れ替える方法ではクロスフェードは難しそうです。

jQueryでimgタグの画像をクロスフェードさせる(成功例)

根本的に考え方を変えます。
HTMLのimgタグを2つ用意してきれいに重ね、上の画像をフェードアウトすればうまくいきそうです。
2枚の画像をぴったりと重ねるにはそれぞれに、position:absoluteを設定してleft,topなどを指定しないと2つはきれいに重なります。ここまでCSSで設定後jQueryでフェードアウトします。
imgタグで画像を表示したものをクロスフェードさせる方法はこれが一番良さそうです。

クロスフェードしながら画像が替わるサンプル
HTMLコード

<p class="img_hover">
 <img src="mascot_rollout.png" alt="" class="img1">
</p>

CSSコード

.img1, .img2{
  position:absolute;
}

jQueryコード

$(function(){
  $(".img_hover").hover(function(){
    $(".img1").before('<img src="mascot_rollover.png" alt="" class="img2" >')
    .fadeOut("slow");
  },
    function(){
	$(".img1").fadeIn("slow",function(){
	 $(".img2").remove();
	});
    });
});

CSSで背景画像を設定して背景画像を変える方法

今度はimgタグを使用せずにCSSのbackground-imageを変更して画像を変更する方法です。
これは先の例のattr()を使用して画像を変更する例と同じような考え方です。
attr()の代わりにcss()を使用しただけです。この方法も画像は入れ替わりますがクロスフェードは難しいです。

background-imageを使用したサンプル
HTMLコード

<p class="img_hover"></p>

CSSコード
.img_hover{
  background-image:url(mascot_rollout.png);
  width:135px;
  height:150px;
}

jQueryコード
$(function(){
  $(".img_hover").hover(function(){
    $(this).css('background-image','url(mascot_rollover.png )');
  },
  function(){
    $(this).css('background-image','url(mascot_rollout.png )');
  });
});

汎用性を高めたCSSの背景画像を変える方法

background-imageを使用し、更に汎用性を高めたサンプル

$(function(){
  $(".img_hover").hover(function(){
    $(this).css('background-image', $(this).css('background-image')
    .replace('_rollout', '_rollover'));
  }, function(){
    $(this).css('background-image', $(this).css('background-image')
    .replace('_rollover', '_rollout'));
   });
});

classを付けたり外して変更する方法

これはjQueryでclassを付けたり外したりして、CSSの設定で切り替える方法です。
classを付けたり外したりする方法
HTMLコード

<p class="img_hover myimg"></p>

CSSコード
.img_hover{
  background-image:url(mascot_rollout.png);
  width:135px;
  height:150px;
}
.img_hover2{
  background-image:url(mascot_rollover.png);
  width:135px;
  height:150px;
}

jQueryコード

$(function(){
  $(".myimg").hover(function(){
    $(this).addClass('img_hover2',1000);
  }, function(){
    $(this).removeClass( "img_hover2" ,1000);
  });
});

入れ子構造のタグにCSSで背景を設定してopacityで設定

ナビゲーションボタンなどa要素が入れ子状態であると仮定してクロスフェードを実現しました。
a要素の代わりにspan要素を使用しても同じ結果を得ることができます。

クロスフェードしながらCSSで画像を変更するサンプル

HTMLコード

<p class="img_hover"><a href="#"></a></p>

CSSコード
.img_hover{
  background-image:url(mascot_rollover.png);
  width:135px;
  height:150px;
}
.img_hover a{
  display:block;
  background-image:url(mascot_rollout.png);
  width:135px;
  height:150px;
}

jQueryコード
$(function(){
  $(".img_hover a").hover(function(){
    $(this).animate({opacity:0,duration: "slow", easing: "linear"});
  }, function(){
    $(this).animate({opacity:1,duration: "slow", easing: "linear"});
  });
});

jQueryでCSSのbackground-mageをクロスフェードさせる(完成形)

素早く何度もイベント対象にホバーしても不具合を起こさないようにstop()を使用した完成形です。
完成のコード
HTMLコード

<p class="img_hover"><a href="#"></a></p>

CSSコード
.img_hover{
  background-image:url(mascot_rollover.png);
  width:135px;
  height:150px;
}
.img_hover a{
  display:block;
  background-image:url(mascot_rollout.png);
  width:135px;
  height:150px;
}

jQueryコード
$(function(){
  $(".img_hover a").hover(function(){
    $(this).stop().animate({opacity:0,duration: "slow", easing: "linear"});
  }, function(){
       $(this).stop().animate({opacity:1,duration: "slow", easing: "linear"});
   });
});