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には
インラインボックスおよび内部のルビまたは表ボックスを除くすべての要素
とありました。
width
と height
が指定できる要素に使えます。
実際に書いてみる
理解を深めるため実際にコードを書いてみます。
See the Pen aspect-raito検証 by yokoyoko (@yokoyoko_code) on CodePen.
aspect-ratio
と width
or height
の検証
「aspect-ratio
と width
」または「aspect-ratio
と height
」を指定した場合、どのような表示になるかを検証しました。
width
height
未指定の場合 → width: 100%
を基準に指定したアスペクト比の高さをとる。
width
または height
を指定した場合 → そのwidth
または height
を基準に高さ、幅をとる。
☆ちなみに width
と height
を両方指定すると、 aspect-ratio
の指定は無視されるようです。
aspect-ratio
と object-fit
を使った画像の表示
記事などのサムネイルをレスポンシブで並べるケースが多いと思います。
指定した比率で拡大縮小(aspect-ratio)と、
指定した範囲内で画像を表示(object-fit)
が同時にできるのはいいですね。
サンプル画像
縦長画像と横長画像、春っぽい画像にしました。メジロ。
アスペクト比の異なる画像を同じ大きさで表示させるのに便利な object-fit
は、以下の条件で使えます。
- img要素などの置換要素
- 置換要素に
width
height
を指定する(auto
以外)
参考記事:
置換要素 - CSS: カスケーディングスタイルシート | MDN
なのでここでは 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-fit
、width
、height
を指定(auto
以外)
になると思います。
場合分けできてスッキリしました。
aspect-ratio
ありがたいです!
さいごに
ずっと「aspect-raito」だと思っていました。 直接入力したおかげで気付けました。
「rate(レート、率)」と混同しました。
英語難しい。
おしまい。