要素のheightの値を固定しないCLS対策

先日とあるサイトでGoogle Search Consoleの「ウェブに関する指標」を確認したところ、「CLSに関する問題」のレポートで不良が多数発生していることに気づきました。

CLS(Cumulative Layout Shift)とはUXのコアウェブバイタルの指標の一つで、ページの読み込み中に起こるレイアウトの移動量(がたつきの大きさ)を示します。

(キャンセルボタンを押そうとしたら読み込み中だったバナーが突然現れ、結果その分ボタンが下に移動してしまい、同意するボタンを誤って押してしまった図解です。似たような経験ありませんか?)

以下のページ内にある動画を見ていただければCLSの概要が掴めるかと思います。

web.dev – https://web.dev/cls/

詳しく調べたところページ上部に設置しているカルーセルのimg要素にheightを指定していないことが原因とわかりました。

対策としてはこのimg要素のheightを固定値にすればいいのですが、レスポンシブサイトの場合、srcsetを使用してアスペクト比の違う画像を差し替えている場合はwidth, heightの値は可変(%指定など)にする必要があり、固定値するとレスポンシブデザインに不都合が起きます。

そこで親要素のpadding-topに画像のアスペクト比の値を設定することでimg要素のheightの値を固定することなくCLS対策することがきました。

<div class="embed-responsive-variable-ratios">  
    <a href="#">   
       <!-- srcsetで画像を差し替える。ピクセル比2倍以上またはデフォルトは縦画像を表示、その他は縦画像表示 -->   
       <img src="https://placehold.jp/750x1334.png" srcset="https://placehold.jp/1366x768.png 1x, https://placehold.jp/750x1334.png 2x"  alt="レスポンシブ画像">  
    </a>  
</div>  
.embed-responsive-variable-ratios a {  
    display: block;  
    position: relative;  
    height: 0;  
    overflow: hidden;  
}  

.embed-responsive-variable-ratios a img {  
    position: absolute;  
    top: 0;  
    left: 0;  
    width: 100%;  
}  

@media screen and (orientation: portrait) { /* 縦画面 */  
    .embed-responsive-variable-ratios a {  
        padding-top: calc(1334 / 750 * 100%);  /* 縦画像の上に内余白 (縦画像の縦サイズ ÷ 画像の横サイズ × 100%) */  
    }  
}  

@media screen and (orientation: landscape) { /* 横画面 */  
   .embed-responsive-variable-ratios a {  
       padding-top: calc(768 / 1366 * 100%); /* 横画の上に内余白 (横画像の縦サイズ ÷ 画像の横サイズ × 100%) */  
   }  
}  

この記事を書いた人