- PageSpeed Insightsで計測したときに、CLS(Cumulative Layout Shift)が「0.33(不良)」になるのが気になっていました。
- 主な原因は、トップページで表示しているカルーセルです。
- CSSの calc() を使って、画面の幅からカルーセルの高さを計算することで、CLSを 0 に改善できました。
1. カルーセルがCLSに悪影響している
CLS(画面ズレ)が起こるのは、トップページにある「カルーセル」が原因です。
確かに、サイトの表示を見てみると、一度 広めにスペースを空けてから ガクッと正しい高さに修正されています。
以前、改善したつもりではあるのですが、いつの間にかズレるようになっていたようです。
過去の話は「[Cocoon] カルーセルの「CLSに関する問題」を改善したいけれど難しそう 」で。
カルーセル自体をやめてしまえば簡単です。
が、やっぱりトップページの「賑やかし」に残しておきたいです。
問題は、カルーセルの「高さ」が記事を読み込む前に事前に測定できないことです。
レスポンシブ・デザインになっていて、画面の表示幅によって一度に表示される記事数が変わるので、高さを決め打ちできません。
1-1. slickの初期化前要素を無理やり表示する(display:block)
Cocoonテーマの「カルーセル」は、テーマ内で「slick」プラグインを利用して動いています1。
slick の内部動作からCLSに対応するように wrap要素の高さを求められないか調べてみました2。
.carousel {
height: 190px;
display:block!important;
overflow-y:hidden;
}
.carousel-content.cf:not(.slick-initialized) {
visibility: hidden;
}
- slickが初期化されるまで.carouselがdisplay:noneなので、強制的に display:blockにしてから min-heightを指定します。
- .carousel がはみ出てしまうので、overflow-y:hiddenに変更します。
この時点で、CLS はなくなります。 - 表示される途中で中身がごちゃごちゃつくのが見えてしまうので、slickが初期化されるまでカルーセル内部をvisibility:hiddenで消しておきます。
確かに、このコードでCLS は 0 になりました。
とはいえ、カルーセルの高さを 190pxで固定しているので、画面幅によってはカルーセル内の記事が見切れてしまう欠点もありました。
2. カルーセルの高さを実測して関係式を求める
そこで、画面幅からカルーセルの高さを求める方法を自分で計算することにしました。
要は、画面幅によってカルーセルの表示枚数が 6分割 → 2分割 まで変わることが、高さが複雑になる原因です。そこで、地道にそれぞれの段階ごとにカルーセルの高さの最大・最小を測ります3。
それを線でつないだグラフがこちら。
通る 2点がわかるので、それぞれの1次関数(y=ax+b)を求めることができます。
- 傾き:a = (y2-y1)/(x2-x1)
- 切片:b = y1 – a x1
分割 | x1 | y1 | x2 | y2 | a | b | calc |
---|---|---|---|---|---|---|---|
2 | 200 | 120 | 480 | 204 | 0.3 | 60 | 30vw+60px |
3 | 481 | 168 | 836 | 244 | 0.214 | 65.0 | 21vw+65px |
4 | 837 | 210 | 1024 | 246 | 0.192 | 48.8 | 19vw+49px |
5 | 1025 | 210 | 1240 | 234 | 0.111 | 95.5 | 11vw+96px |
6 | 1241 | 210 | 1800 | 210 | 210px |
Cocoonテーマで指定する コンテンツ幅によって数式は変わります。
2-1. CSSの calc と vw
CSSでは、高さを幅を使って計算するには calc()を使います4。カッコの中に計算式を入力します。
.carousel-in.wrap .carousel-content{
height:calc(30vw + 60px);
}
}
vw は、幅の1%分に相当します。
ですので、y = 0.3 x + 60 の関係なら
calc(30vw+60px)
で計算できるわけです。
あとは、「@media screen and (max-width: 836px){」などのように、画面幅ごとにスタイルを設定していきます。
3. できあがったCSS
できあがった CSS はこちら。
/** cocoon カルーセルを使用している場合のCLS改善
* 2023-07-03 *
* */
@media screen {/* 6分割 */
.carousel-in.wrap .carousel-content{
height:210px;
}
}
@media screen and (max-width: 1240px){/*5*/
.carousel-in.wrap .carousel-content{
height:calc(11vw + 100px);
}
}
@media screen and (max-width: 1024px){/*4*/
.carousel-in.wrap .carousel-content{
height:calc(19vw + 50px);
}
}
@media screen and (max-width: 836px){/*3*/
.carousel-in.wrap .carousel-content{
height:calc(21vw + 65px);
}
}
@media screen and (max-width: 480px){/*2*/
.carousel-in.wrap .carousel-content{
height:calc(30vw + 60px);
}
}
.carousel-content>a{
display:none;
}
無事に CLS が 0 になりました。
(補足)
- カルーセル非使用時でもslickを使いたい | Cocoonテーマに関する質問 | Cocoon フォーラム
- 【adsence】CLS に関する問題: 0.25 超の修正方法【Cocoon】 | オランダで生きていく
- Chromeの「検証」で調べましたが、多少 誤差があります
- CSSのcalc()を使って幅や高さを計算式で指定する-ウェブ制作小ネタTIPS