要素の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対策することがきました。

<style>
.embed-responsive-variable-ratios picture {  
    display: block;  
    position: relative;  
    height: 0;  
    overflow: hidden;  
}  

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

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

@media screen and (orientation: landscape) { /* 横画面 */  
   .embed-responsive-variable-ratios picture  {  
       padding-top: calc(768 / 1366 * 100%); /* 横画の上に内余白 (横画像の縦サイズ ÷ 画像の横サイズ × 100%) */  
   }  
}  
</style>
<div class="embed-responsive-variable-ratios">
    <picture> 
        <source media="(orientation: portrait)" srcset="https://placehold.jp/768x1366.png?text=縦画像(768x1366) 1x, https://placehold.jp/1536x2732.png?text=縦画像(1536x2732) 2x">
        <source media="(orientation: landscape)" srcset="https://placehold.jp/1366x768.png?text=横画像(1366x768) 1x, https://placehold.jp/2732x1536.png?text=横画像(2732x1536) 2x">   
        <img src="https://placehold.jp/1366x768.png?text=横画像(1366x768)" alt="レスポンシブ画像">  
    </picture>
</div>
レスポンシブ画像

See the Pen by 本田類二 (@curledtail_h) on CodePen.

この記事を書いた人