CSSプロパティの「aspect-ratio」について(aspect-ratioその2)

cssプロパティの aspect-ratio という、とても便利なものを最近見つけました。
大体のブラウザで使えます(詳細はこちら)。

使い方を実際に書いて調べてみます。

CSSメディアクエリの「aspect-ratio」やアスペクト比については(その1)にまとめました。
aspect-ratio」についてもそちらで調べています。

cssプロパティの 「aspect-ratio」

参考記事:

CSS aspect-ratioプロパティの基礎知識、便利な使い方、実装に必要なプログレッシブエンハンスメント | コリス

以前レイアウトシフト(CLS)の対策を考えた記事や、レスポンシブ対応の画像の表示についてまとめた記事を書きました。

aspect-ratio を使うと、これらの書き方がさらに簡単になります。
一言でいうと「要素にアスペクト比を指定する」です。

書き方

aspect-ratio: 幅 / 高さ

です。

値は計算したものでも書けます。 縦:横が1:1や1:2の場合など簡単なものであれば、aspect-ratio: 1 aspect-ratio: 0.5 と書いてもアスペクト比が分かりますね。
計算してアスペクト比が分かりにくくなってしまうのであれば「幅 / 高さ」のままが良さそうです。

プロパティが効く要素

MDNには

インラインボックスおよび内部のルビまたは表ボックスを除くすべての要素

とありました。

widthheight が指定できる要素に使えます。

実際に書いてみる

理解を深めるため実際にコードを書いてみます。

See the Pen aspect-raito検証 by yokoyoko (@yokoyoko_code) on CodePen.

aspect-ratiowidth or heightの検証

aspect-ratiowidth」または「aspect-ratioheight」を指定した場合、どのような表示になるかを検証しました。

width height 未指定の場合 → width: 100% を基準に指定したアスペクト比の高さをとる。
width または height を指定した場合 → そのwidth または height を基準に高さ、幅をとる。

☆ちなみに widthheight を両方指定すると、 aspect-ratio の指定は無視されるようです。

aspect-ratioobject-fit を使った画像の表示

記事などのサムネイルをレスポンシブで並べるケースが多いと思います。

指定した比率で拡大縮小(aspect-ratio)と、
指定した範囲内で画像を表示(object-fit)
が同時にできるのはいいですね。

サンプル画像

縦長画像と横長画像、春っぽい画像にしました。メジロ

f:id:yokoyoko_115:20220306005545j:plain f:id:yokoyoko_115:20220306005600j:plain

アスペクト比の異なる画像を同じ大きさで表示させるのに便利な object-fit は、以下の条件で使えます。

  • img要素などの置換要素
  • 置換要素に width height を指定する(auto 以外)

参考記事:

置換要素 - CSS: カスケーディングスタイルシート | MDN

CSS – object-fitが効かない場合

なのでここでは object-fit を設定したimg要素に対して、

  • aspect-ratio も一緒に指定する
  • img要素の親要素に aspect-ratio を指定する

どちらが良いのか検証します。

ちなみに両方ともアスペクト比 1:1 で、object-fit: cover を指定しました。

***

結果、どちらでもうまく表示されました。
メジロの位置も、中央でトリミングされている表示になっています。

前者でも問題ないというのが意外でした。

レイアウトシフト対策にaspect-ratioが有効

レイアウトシフトについて書いた記事から、新しいことが分かりました!

<img src="image.jpg" alt="hoge" width="400" height="300">

と書けば、400x300pxの表示領域を画像読み込み前に確保しているのかと思いきや、
今は進化して width height の属性値からアスペクト比を出しているのです。

Cumulative Layout Shift を最適化する

そしてすべてのブラウザーUA スタイルシートは、要素に設定されている既存の width と height 属性に基づいてデフォルトのアスペクト比を追加します。

width、height属性値はピクセル値としてはもはや見られていないのでしょうね。
(%付きの値もなのでしょうか)

img {
  aspect-ratio: attr(width) / attr(height);
}

アスペクト比は、画像が読み込まれる前に width と height 属性に基づいて計算されます。この情報は、レイアウト計算の初期段階で供給されます。画像の幅を特定の値 (たとえば width: 100%) に設定するように指示があると、アスペクト比はすぐに高さの計算に使用されます。

画像が読み込まれる前、早い段階でcssの処理があって、表示領域が確保されるのですね。

UA スタイルシート側でこのような指定があったとは知りませんでした。

こちらの書き方は、読み込んだ画像のアスペクト比で表示させる場合に有効です。

object-fit を使うような、画像の一部分を表示させたりトリミングする場合は、Codepenで書いた方法でいいのだと思いました。

つまりレイアウトシフトの対策方法は

  • 画像を全表示の場合:
    img要素にwidth、height属性を指定(アスペクト比でも元画像のサイズでもOK)+ width: 100%; height: auto; などで縦・横いずれかの大きさを指定する
  • 画像を一部分表示(トリミングする場合):
    aspect-ratioアスペクト比を指定 + 置換要素(img要素など)に object-fitwidthheight を指定(auto 以外)

になると思います。

場合分けできてスッキリしました。

aspect-ratio ありがたいです!

さいごに

ずっと「aspect-raito」だと思っていました。 直接入力したおかげで気付けました。

「rate(レート、率)」と混同しました。

英語難しい。

おしまい。