CLSとaspect-ratio

これまでにこんな経験はないでしょうか。

Webサイトのアクセスしてリンクをクリックしようとしたら、直前で広告の画像が表示されてしまい、リンクの位置が下にずれて、間違って広告をクリックしてしまった。

このようなことはユーザー体験を低下させます。

これは、画像などの大きいコンテンツが、Webサイトの表示から遅れてロードされることが原因です。

このような表示の遅延によってレイアウトが変わってしまうことをCLS(Cumulative Layout Shift)といいます。

GoogleがWebサイトを評価するときの一つの指標としてCLSが使われている可能性があります。

そのため、CLSのスコアが低い(しばしなレイアウトのずれが発生する)と、SEOにも影響する可能性があります。

実際にCLSを起こしてみる

簡単なサンプルでCLSを起こしてみます。

画像(img1.PNG)はできるだけ大きいサイズの方が分かりやすいです。

click me の div があなたがクリックしたい部分とします。

<body>
  <img src="./img1.PNG" />
  <div>click me</div>
</body>
div {
    background: pink;
}
img {
  width: 100%;
  height: auto;
}

このサンプルでは画像をブラウザの幅に合わせてレスポンシブに表示したいために、横を100%としています。

このサンプルをChromeブラウザ開くのですが、その前にネットワークが遅い状態にします。

F12キーで開発ツールを起動し、Network タブをクリックします。

スクリーンショットの「No throttling」と書かれているあたりをクリックし、「Slow 3G」に変更します。

作成したhtmlをブラウザで表示します。この時に、SHIFT + CTRL + R でキャッシュを使わないロードをします。

すると、一瞬でありますが、ピンクのdivが表示されます。

その後、画像が表示され始めると、ピンクのdivが下に押し出されます。これがCLSです。

aspect-ratio を使ってCLSを回避する

aspect-ratio を使うことでCLSを回避できます。

div {
    background: pink;
}
img {
  width: 100%;
  height: auto;
  aspect-ratio: 666/833; // ここは実際の画像の縦/横
}

このようにすることで、ブラウザは画像の横のサイズから縦のサイズを事前に知ることができるため、画像を表示するスペースを先に確保するので、CLSは発生しません。

このように、画像はレスポンシブに表示したいので画像の高さは指定できないがCLSも防ぎたい、という場合に aspect-ratio は便利です。

なお、レスポンシブにしない場合は、img の width と height を固定で指定できるので、その場合はCLSは発生しません。

参考情報

https://developer.mozilla.org/ja/docs/Web/Media/images/aspect_ratio_mapping