はじめに
HTMLで画像を表示する際に利用する<picture>
<img>
には多くの属性があったり、適切な画像に切り替える方法などありますが、これまでに学んできた知識を一度まとめたいと思い記事にしました。
基本的によく利用する属性をまとめています。
(備忘録です)
目次
基本形
<img src="./sample.jpg" alt="画像の代替テキスト" />
<img>
を利用する場合はsrc
属性とalt
属性を利用します。
src
には画像へのパスを入れ、alt
には画像を説明する代替テキストをいれます。
alt
属性は必須ではありませんが、アクセシビリティ向上のため基本的に設定することが推奨されます。
スクリーンリーダーの読み上げや、ネットワークエラー・リンク切れなどで画像を表示できない場合でalt
に設定したテキストが代替テキストとして表示されます。
alt
に設定する代替テキストをどのように記述すればよいか迷うことがよくあると思いますが、以下のURLがとても参考になります。
widthとheight
画像の固有の幅と高さを設定します。
<img src="./sample.jpg" alt="" width="640" height="427" />
任意ですが、レイアウトシフト(CLS)の対策で基本的には記述するのがベターです。
レイアウトシフトとは、Webサイトを開いたときにページの読み込み中または読み込み後に発生する、予期せぬレイアウトの変化のことを指します。画像や広告などの動的に読み込まれるコンテンツなどが原因で起こり、ユーザー体験に悪影響を及ぼすことがあります。
(以下参考URL内の動画でページのレイアウトが変わる様子が示されており、慌てている様子がちょっとおもしろいです)
VSCodeを利用している場合、コマンドパレットから「イメージサイズの更新」を選択することで、自動的にwidth
とheight
を<img>
に含めることが可能です。
(画像までのパスが正しく通っている必要があります)
loading属性
loading
属性はブラウザがどのように画像を読み込むかを示す属性値です。
いわゆる遅延読み込み設定です。
<img src="./sample.jpg" alt="" loading="lazy" width="640" height="427" />
loading
属性を設定しない場合eager
になります。(遅延読み込みしない設定)
eager
lazy
と2つの値がありますが、自分はファーストビュー付近にある画像以外の<img>
要素すべてにlazy
をつけています。
ページの読み込み速度に影響する画像は画面外で遅延読み込みすることによって、初回読み込みの時間を短縮することができます。
またlazy
指定の場合は必ずwidth
height
をつけます。初期状態で幅・高さが0pxになるので、つけておかないと読み込み時にレイアウトシフトが発生してしまいます。
decoding
属性について
loading
属性と合わせてよく紹介されているdecoding="async"
ですが、挙動について理解できておらず、また以下のURL参考に自分もブラウザの挙動に任せることとしました。
picture
<picture>
はPC・SPなどで表示する画像が違うものや、iPhoneのRetinaディスプレイなどの画面や端末の条件に応じて画像を出し分けられる要素です。
メディアクエリで画像を出し分け
例えばアスペクト比の異なるPC用とSP用の画像を切り替える場合、source
を用いて以下のように分岐させることができます。
<picture>
<source
media="(max-width: 576px)"
srcset="/sample_sp.jpg"
width="640"
height="960"
/>
<img src="/sample_pc.jpg" width="640" height="960" alt="" />
</picture>
これで基本sample_pc.jpgを読み込んで表示し、画面幅が576px以下の場合は代わりにsample_sp.jpgを表示するようになります。
display:noneでの切り替え
よく記事などで紹介されている、display:noneを利用した画像切り替えがありますが、pc・sp両方の画像を読み込んでしまうので、基本的にはpicture/sourceを利用する方法を推奨します。
(picture/sourceだと片方しか読み込まれないのでページの読み込み時間がその分早くなります。)
ちなみにsource
にもwidth
height
を指定できるので、アスペクト比が異なる場合は記述したほうがよいです。
また、PC・SPで全く別の画像を出し分ける時は、alt
テキストに気をつけた方がよいです。
source
にはalt
テキストが設定できず、<img>
にもalt
は1つしか設定できないので...
(この場合の最適解がわからない)
画面解像度での出し分け
MacやiPhoneに搭載されているRetinaディスプレイなどの高解像度ディスプレイに対応する場合はsrcset
属性を使います。
<picture>
<source srcset="./sample@2x.jpg 2x, ./sample@3x.jpg 3x" />
<img src="./sample.jpg" width="640" height="960" alt="" />
</picture>
srcset
属性に画像へのURLと対応する解像度を記述します。これで一般的なディスプレイと高解像度ディスプレイでの画像の出し分けが可能になります。
画面幅(ビューポート)での出し分け
ブラウザの画面幅に応じて、画像を出し分けることも可能です。
<picture>
<source srcset="./sample-576w.jpg 576w, ./sample-992w.jpg 992w" />
<img src="./sample.jpg" width="640" height="960" alt="" />
</picture>
この記述だと画面幅が576pxの場合にsample-576w.jpgが、992pxの場合にsample-992w.jpgが表示されるようになります。
また、sizes
属性を利用することで場面に応じた画像サイズを指定する事が可能になります。
<picture>
<source srcset="./sample-576w.jpg 576w, ./sample-992w.jpg 992w" sizes="20vw"/>
<img src="./sample.jpg" width="640" height="960" alt="" />
</picture>
例えば上記の指定だとsizes
属性の指定値が20vw
になっているため、画面幅の1/5サイズで足りる画像を選択して表示することができます。
(例:画面幅1920pxの場合、画像のサイズは1/5の384pxになり、表示される画像はsample-576w.jpgになる)
srcset
sizes
属性ともに指定されている値が適切かどうかを検証してくれるRespImageLintというサービスがあるみたいです。
(下記参考記事)
画像ファイル形式について
自分がよく使う拡張子については以下の4つです。
- JPEG
- PNG
- SVG
- WebP
ベクター形式(アイコンやイラストなど)のデータについては基本svgを、ラスター形式(写真など)のデータについては基本的にはWebPを扱うことが多いです。
今までWebPのフォールバックとしてjpg,pngを<picture>
で出し分けて実装していましたが、Safariも14系から対応してるのでそのままWebPのみ利用する形で基本問題ないです。
WebPについては基本的にjpgやpngよりは軽くなりますが、場合によってはWebPの方が重くなることもあるので一度圧縮してみて比較しどちらを利用するか決めた方がいいです。
(pngとかは内容によってはWebPより軽い事があります。)
また、高画質な上に圧縮率も高いAVIFという次世代のファイル形式もモダンブラウザで対応しているので、こちらも徐々に移行できたらいいなと考えています。
(safariが16系からなのでもう少し先かな...)
まとめ
画像はリソースのダウンロードでWebフォントに次いでネックなところなので、今後も知識をアップデートしつつ、適切な処理方法を行いたいです。
参考文献