CSS の aspect-ratio プロパティ

レスポンシブ レイアウトで間隔を維持するのに役立つ CSS プロパティ。

アスペクト比

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 89.
  • Safari: 15.

Source

アスペクト比は通常、幅:高さ、または x:y の形式で 2 つの整数とコロンで表されます。写真撮影で最も一般的なアスペクト比は 4:3 と 3:2 ですが、動画や最近のコンシューマー カメラでは 16:9 のアスペクト比が一般的です。

同じアスペクト比の 2 枚の画像。1 つは 634 x 951 ピクセル、もう 1 つは 200 x 300 ピクセルです。どちらもアスペクト比は 2:3 です。
同じアスペクト比の画像 2 枚。1 つは 634 x 951 ピクセル、もう 1 つは 200 x 300 ピクセルです。どちらもアスペクト比は 2:3 です。

レスポンシブ デザインの登場により、アスペクト比の維持はウェブ デベロッパーにとってますます重要になっています。特に、使用可能なスペースに応じて画像のサイズが異なり、要素のサイズが変化する場合に重要です。

アスペクト比の維持が重要になる例を次に示します。

  • レスポンシブ iframe を作成する。iframe の幅は親の幅の 100% で、高さは特定のビューポート比率を維持する必要がある
  • 画像、動画、埋め込みの固有のプレースホルダ コンテナを作成し、アイテムの読み込み時にレイアウトが再調整されてスペースが占有されるのを防ぐ
  • インタラクティブなデータ可視化や SVG アニメーションのための均一でレスポンシブなスペースを作成する
  • カードやカレンダーの日付などの複数要素のコンポーネントに対して、均一でレスポンシブなスペースを作成する
  • さまざまなサイズの複数の画像に対して、均一でレスポンシブなスペースを作成する(object-fit と併用可能)

object-fit

アスペクト比を定義すると、レスポンシブ コンテキストでメディアのサイズを調整するのに役立ちます。このバケットのもう 1 つのツールは object-fit プロパティです。これを使用すると、ブロック内のオブジェクト(画像など)がブロックをどのように埋めるかを記述できます。

object-fit デモの可視化
さまざまな object-fit 値を紹介します。Codepen のデモをご覧ください。

initialfill の値は、スペースを埋めるように画像を再調整します。この例では、ピクセルが再調整されるため、画像が縮小されてぼやけます。理想的ではありません。object-fit: cover では、画像の最小の寸法を使用してスペースを埋め、この寸法に基づいて画像を切り抜いてスペースに収めます。下限で「ズームイン」します。object-fit: contain は、画像全体が常に表示されるようにします。これは cover の反対で、最も大きい境界(上記の例では幅)のサイズを取得し、固有のアスペクト比を維持しながらスペースに収まるように画像のサイズを変更します。object-fit: none の例では、画像が自然なサイズで中央(デフォルトのオブジェクト位置)で切り抜かれています。

object-fit: cover は、さまざまなサイズの画像を扱う際に、均一なインターフェースを確保するためにほとんどの状況で機能しますが、この方法では情報が失われます(画像が最も長いエッジで切り抜かれます)。

これらの詳細が重要な場合(化粧品のフラットレイを扱う場合など)、重要なコンテンツを切り抜くことはできません。したがって、理想的なシナリオは、切り抜きなしで UI スペースに収まるさまざまなサイズのレスポンシブ画像です。

以前のハック: padding-top を使用してアスペクト比を維持する

padding-top を使用して、カルーセル内の投稿プレビュー画像のアスペクト比を 1:1 に設定します。
padding-top を使用して、カルーセル内の投稿プレビュー画像の縦横比を 1:1 に設定します。

レスポンシブにするには、アスペクト比を使用します。これにより、特定の比率のサイズを設定し、残りのメディアを個々の軸(高さまたは幅)に基づいて配置できます。

現在、画像のアスペクト比を維持するためのクロスブラウザ ソリューションとして広く受け入れられているのは、「Padding-Top Hack」です。このソリューションには、親コンテナと絶対配置された子コンテナが必要です。アスペクト比をパーセンテージとして計算し、padding-top として設定します。次に例を示します。

  • アスペクト比 1:1 = 1 / 1 = 1 = padding-top: 100%
  • アスペクト比 4:3 = 3 / 4 = 0.75 = padding-top: 75%
  • アスペクト比 3:2 = 2 / 3 = 0.66666 = padding-top: 66.67%
  • アスペクト比 16:9 = 9 / 16 = 0.5625 = padding-top: 56.25%

アスペクト比の値が特定できたので、親コンテナに適用します。たとえば次のようになります。

<div class="container">
  <img class="media" src="..." alt="...">
</div>

次のような CSS を記述できます。

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

aspect-ratio でアスペクト比を維持する

アスペクト比を使用して、カルーセル内の投稿プレビュー画像のアスペクト比を 1:1 に設定します。
aspect-ratio を使用して、カルーセル内の投稿プレビュー画像の縦横比を 1:1 に設定する。

残念ながら、これらの padding-top 値の計算は直感的ではなく、追加のオーバーヘッドとポジショニングが必要です。新しい固有の aspect-ratio CSS プロパティを使用すると、アスペクト比を維持するための言語がより明確になります。

同じマークアップで、padding-top: 56.25%aspect-ratio: 16 / 9 に置き換え、aspect-ratiowidth / height の指定された比率に設定できます。

padding-top を使用する
.container {
  width: 100%;
  padding-top: 56.25%;
}
aspect-ratio の使用
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

padding-top の代わりに aspect-ratio を使用する方がはるかに明確であり、パディング プロパティをオーバーホールして通常のスコープ外の処理を行うこともありません。

この新しいプロパティでは、アスペクト比を auto に設定する機能も追加されます。この場合、「固有のアスペクト比を持つ置換要素はそのアスペクト比を使用します。それ以外の場合、ボックスには優先アスペクト比がありません。」auto<ratio> の両方が指定されている場合、優先アスペクト比は、widthheight で割った指定の比率になります。ただし、固有のアスペクト比を持つ置換要素の場合は、そのアスペクト比が代わりに使用されます。

例: グリッドの一貫性

これは、CSS グリッドや Flexbox などの CSS レイアウト メカニズムでも非常に効果的です。スポンサー アイコンのグリッドなど、アスペクト比を 1:1 に維持したい子を持つリストを考えてみましょう。

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
さまざまなアスペクト比の寸法で親要素を持つグリッド内の画像。Codepen でデモをご覧ください。

例: レイアウト シフトを防ぐ

aspect-ratio のもう一つの優れた機能は、プレースホルダ スペースを作成して累積レイアウト シフトを防ぎ、ウェブ バイタルを改善できることです。最初の例では、Unsplash などの API からアセットを読み込むと、メディアの読み込みが完了したときにレイアウト シフトが発生します。

読み込まれたアセットにアスペクト比が設定されていない場合に発生するレイアウト シフトの累積値の動画。この動画は、エミュレートされた 3G ネットワークで録画されています。

一方、aspect-ratio を使用すると、このレイアウト シフトを防ぐためのプレースホルダが作成されます。

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
読み込まれたアセットに、アスペクト比が設定された動画が設定されています。この動画は、エミュレートされた 3G ネットワークで録画されています。Codepen でデモをご覧ください。

ボーナス ヒント: アスペクト比の画像属性

画像の縦横比を設定するもう 1 つの方法は、画像属性を使用することです。画像のサイズを事前に把握している場合は、そのサイズを widthheight として設定することがベスト プラクティスです。

上記の例では、サイズが 800 × 600 ピクセルであるため、画像マークアップは <img src="image.jpg" alt="..." width="800" height="600"> のようになります。送信された画像のアスペクト比が同じで、必ずしも正確なピクセル値ではない場合でも、画像属性値を使用して比率を設定し、width: 100% のスタイルと組み合わせることで、画像が適切なスペースを占めるようにすることができます。すべてをまとめると、次のようになります。

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

最終的に、効果は CSS を介して画像に aspect-ratio を設定するのと同じになり、レイアウト シフトの累積を回避できます(Codepen のデモを参照)。

まとめ

複数の最新ブラウザでリリースされた新しい aspect-ratio CSS プロパティを使用すると、メディアとレイアウト コンテナで適切なアスペクト比を維持するのが少し簡単になります。

写真: Amy ShamblenLionel Gustave(Unsplash 経由)。