2016年11月から勧告となったHTML5.1の大きな変更点として<picture>
要素とsrcset属性1によるレスポンシブイメージ (responsive images)2の採用がありました。
レスポンシブイメージを利用すればJSやCSSを使わずにブラウザの幅やピクセル密度(Retinaなど)に応じて、異なる画像を読み込む事ができます。
レスポンシブイメージ自体についての詳説は下記をご参照ください。
- srcset属性について
- レスポンシブイメージで画像の表示を最適化 〜CSSもJSもいらないHTML 5.1の新機能 – ICS MEDIA
- srcset と sizes
- レスポンシブイメージのネイティブサポート
例
<img>
要素をこんな風に書くと
<img src="lighthouse-160.jpg" alt="灯台" sizes="80vw" srcset="lighthouse-160.jpg 160w, lighthouse-320.jpg 320w, lighthouse-640.jpg 640w, lighthouse-1280.jpg 1280w">
こんな風に画像の出し分けが出来てとても便利です。
困ったこと
さて、私も早速srcset属性1を使ってこれは便利だと喜んでいたのですが、ある日デザイナーさんにレスポンシブイメージに対して「ロールオーバー3で画像を別な画像に切り替えて欲しい」と言われて困ってしまいました。
よく紹介されている画像切り替え手法はどれもレスポンシブイメージとしっくりこない感じがしたんですよね。
よく使われる画像切り替え方法
- CSSスプライトを作りbackground-positionを切替える
- CSSでbackground-imageを切替える
- CSSでマウスオーバー時
<img>
要素非表示を指定 <img>
要素にonmouseout属性, onmouseover属性を記述- Javascriptで
<img>
要素のsrc属性を書き換える
よく使われるロールオーバー3画像切り替え方法には上記がありますが、1.はアイコンセットなどでは有効な手法だが、大きな画像には向いていない。2.と3.は事前にロールオーバー用の画像を読み込ませるので、余分な画像を事前ロードさせない(から表示の高速化にも役立つ)というレスポンシブイメージの理念と対立しちゃってる感がある。
5.もHTMLだけで実現できるというメリットが薄くなる感じがするので微妙。…というわけで4. <img>
要素にonmouseout属性, onmouseover属性を記述が一番相性が良さそうだと思いました。
本題
onmouseout属性, onmouseover属性でsrcset属性に指定した画像を切り替える
というわけで実装します。
<a href=""> <img src="/img/sample.png" srcset="/sample@2x.png 2x, /img/sample.png 1x" onmouseover="this.setAttribute('srcset','/img/sample_hover@2x.png 2x, /img/sample_hover.png 1x');" onmouseout="this.setAttribute('srcset','/img/sample@2x.png 2x, /img/sample.png 1x');" alt="サンプル画像"> </a>
上記のように書けばレスポンシブイメージでも画像切り替えが出来ました!
なお従来は
<a href=""> <img src="/img/sample.png" onmouseover="this.src='/img/sample_hover.png'" onmouseout="this.src='/img/sample.png'" alt="サンプル画像"> </a>
のように書けばOKだったので難しくなってはいますね。日々精進!す。
1. 読み方は「ソースセット」。 ↩
2. レスポンシブデザイン (RWD) はまた別物です。ややこしいですね。↩
3. ロールオーバー (roll-over)、マウスオーバー (mouseover)、ホバー (hover)…全部ほぼ同じ意味です。ややこしい。 ↩