CLS改善のための画像サイズ指定方法の整理
Lighthouseなどで出てくる項目の一つにあるCLS(Cumulative Layout Shift)。
その要因の一つである「ディメンションのない画像」について、ひいては画像のサイズ指定方法を調べたので、整理する。
画像要素にwidth属性とheight属性をつけないとどうなるのか
<img src="img-cat.jpg" alt="" style="width: 100%;">
ブラウザが画像のダウンロードが開始されるまで縦横比を特定することができない。その後、画像が読み込まれる時にスペースが割り当てられ、下部の要素が押し下げられることでレイアウトシフト(レイアウトのずれ)が発生する可能性がある。
解決策の方向性
ブラウザにあらかじめ画像や動画を表示させるために必要なスペースを確保させる。
そのためにwidth属性&height属性またはCSSのaspect-ratioプロパティを使用する。
解決策1:width属性とheight属性の明示
width属性とheight属性をつけることで、それらをもとにアスペクト比を計算し、画像読み込み前に適切なスペースを確保する。
加えてCSSの指定を行うことで画像を拡縮させる。
<img class="sample-01" src="img-cat.jpg" alt="" width="948" height="632"/>
.sample-01 {
width: 100%;
height: auto;
}
- width属性&height属性…アスペクト比の計算に利用
- CSS width: 100%;…実際に表示させる際の横幅の調整
- CSS height: auto;…実際に表示させる際のアスペクト比を維持した高さの算出
解決策2:CSS aspect-ratioプロパティの利用
画像のレイアウトが特定のアスペクト比であることがデザイン要件である場合はCSS aspect-ratioプロパティによる方法が好ましいようだ。(例…サムネイル一覧、ヒーローイメージなど)
この方法だと画像が持つ本来の比率に依存せず、指定した比率で表示領域を確保できる。
.sample-02 {
aspect-ratio: auto 3 / 2;
width: 100%;
height: 100%;
}
aspect-ratioプロパティについて、
autoと比率を両方指定すると内在的な縦横比をもつ要素(imgタグのような)の時はauto値が使用される。
画像の実際の比率と表示させたいスペースの比率が異なるとき、auto値がないとaspect-ratioプロパティで設定した比率に拡縮してしまう(object-fit: fill;のような見え方)。
aspect-ratioプロパティの詳しい仕様については以下を参照。
アートディレクションするとき
picture要素内のsource要素にもwidth属性がつけられる。
<picture>
<source media="(min-width: 960px)" srcset="img-cat.jpg" width="948" height="632"/>
<img src="img-cat-sp.jpg" class="sample-01" alt="" width="660" height="920"/>
</picture>
参考資料
- 「Cumulative Layout Shift の最適化」https://web.dev/articles/optimize-cls?utm_source=lighthouse&utm_medium=devtools&hl=ja#images_without_dimensions
- 「Avoiding <img> layout shifts: aspect-ratio vs width & height attributes」https://jakearchibald.com/2022/img-aspect-ratio/
- 「aspect-ratio」https://developer.mozilla.org/ja/docs/Web/CSS/aspect-ratio
- 「Jank-free page loading with media aspect ratios」https://blog.logrocket.com/jank-free-page-loading-with-media-aspect-ratios/
- 「imgタグのsrcset・sizes属性とpictureタグの使い方 レスポンシブイメージで画像表示を最適化」https://ics.media/entry/13324/
Discussion