Back

CSS Aspect Ratioの仕組み

CSS Aspect Ratioの仕組み

画像コンテナにwidth: 100%を設定しても、画像が読み込まれるまで高さがゼロに縮小してしまい、ユーザーが嫌がるレイアウトシフトが発生します。CSSのaspect-ratioプロパティは、この問題を直接解決し、コンテンツが到着する前にスペースを確保できるようにします。

この記事では、aspect-ratioプロパティがCSSのサイズ計算にどのように関与するか、置換要素と非置換要素でどのように異なるか、そしてレスポンシブレイアウトのための古いpadding-hackテクニックをどのように置き換えるかについて説明します。

重要なポイント

  • aspect-ratioプロパティは、少なくとも一方の次元がautoの場合にのみ適用される、推奨される幅と高さの比率を定義します。
  • これは要素のボックスを形成するものであり、内部のメディアではありません—画像や動画がスペースをどのように埋めるかを制御するには、object-fitと組み合わせます。
  • レガシーなpadding-bottomハックをクリーンに置き換え、ラッパー要素、絶対配置、不明瞭な計算が不要になります。
  • flexboxやgridコンテキストでは、計算されたaspect-ratioの寸法を上書きまたは競合する可能性のある自動サイズ調整の相互作用に注意してください。

CSS Aspect-Ratioプロパティの理解

aspect-ratioプロパティは、要素のボックスに対する推奨される幅と高さの比率を定義します。重要なのは「推奨される」という言葉です—少なくとも一方の次元が自動の場合にのみ有効になります。

.video-container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

ここでは、幅が明示的(親の100%)であるため、ブラウザは16:9の比率を使用して高さを自動的に計算します。widthheightの両方を明示的に設定した場合、通常のレイアウト計算では確定的な寸法が優先されるため、aspect-ratioは通常、使用されるサイズに影響しません。

構文と値

このプロパティは3つの形式を受け入れます:

aspect-ratio: 16 / 9;      /* 幅 / 高さの比率 */
aspect-ratio: 1;            /* 1 / 1と同じ(正方形) */
aspect-ratio: auto 3 / 2;  /* フォールバック比率を持つauto */

autoキーワードは、要素に自然なアスペクト比が存在する場合、それを使用するようブラウザに指示します。auto 3 / 2の組み合わせは、置換要素には自然な比率を使用し、それ以外の場合は3/2を使用することを意味します。

置換要素と非置換要素

このプロパティは、要素のタイプによって異なる動作をします。

置換要素(<img><video><iframe>)は固有の寸法を持ちます。デフォルトでは、aspect-ratio: autoはそれらの自然な比率を使用します。aspect-ratio: auto 16/9を指定すると、ブラウザは読み込まれた後にメディアの自然な比率を使用しますが、事前に16/9を使用してスペースを確保し、レイアウトシフトを防ぎます。

非置換要素(<div><section>)には固有の比率がありません。width: 200px<div>aspect-ratio: 1を設定すると、200×200の正方形が生成されます。このプロパティはボックスの寸法を直接制御します。

Aspect-Ratioはボックスを形成し、メディアではない

重要な区別:aspect-ratioコンテナの寸法を制御するものであり、メディアがどのようにそれを埋めるかではありません。画像や動画の場合、ボックス内のメディアの動作を制御するにはobject-fitを使用します:

.thumbnail {
  aspect-ratio: 1;
  object-fit: cover;
}

これにより、画像が領域をカバーし、必要に応じてトリミングされる正方形のコンテナが作成されます。

CSS Aspect Ratio vs. Paddingハック

aspect-ratioがブラウザでサポートされる前、開発者はpadding-bottomパーセンテージトリックを使用していました:

/* レガシーなpaddingハック */
.video-wrapper {
  position: relative;
  padding-bottom: 56.25%; /* 9/16 = 0.5625 */
  height: 0;
}
.video-wrapper iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

これは、paddingのパーセンテージが親のに対して計算されるため、比率ベースの高さを作成できるからです。しかし、ラッパー要素、絶対配置、不明瞭な計算が必要です。

モダンなアプローチはよりクリーンです:

.video-wrapper {
  aspect-ratio: 16 / 9;
}
.video-wrapper iframe {
  width: 100%;
  height: 100%;
}

デフォルトとしてaspect-ratioを使用してください。IEなどのレガシーブラウザをサポートする必要がある場合にのみ、paddingハックを予約してください。

FlexboxとGridでのAspect-Ratio

flexboxやgridレイアウトでaspect-ratioを使用することは可能ですが、自動サイズ調整の相互作用により予期しない結果が生じる可能性があります。

CSS Gridでは、aspect-ratioは自動サイズのトラックで自然に機能します:

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.grid-item {
  aspect-ratio: 1;
}

各アイテムは正方形になり、高さはグリッドで決定された幅に一致します。

Flexboxでは、flex-growflex-shrinkが計算された幅に影響し、それがaspect-ratioを介して高さを決定することに注意してください。アイテムが予期せず伸びる場合は、flexプロパティを確認してください。アイテムに明示的なwidthまたはflex-basisを設定すると、aspect-ratioが動作する安定した寸法が得られます。

両方のレイアウトシステムで、コンテンツがaspect-ratioで制約された高さをオーバーフローする場合は、アイテムにmin-height: 0を設定してください。

Aspect-Ratioを使用した実用的なレスポンシブレイアウト

レスポンシブカード画像の一般的なパターンは次のとおりです:

.card-image {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

埋め込み動画の場合:

.embed-container {
  width: 100%;
  max-width: 800px;
  aspect-ratio: 16 / 9;
}

両方のパターンは、レイアウトスペースを即座に確保し、累積レイアウトシフト(CLS)を排除します。

まとめ

aspect-ratioプロパティは、少なくとも一方の次元がautoの場合に使用される推奨比率を定義します。これは要素のボックスを形成するものであり、メディアコンテンツではありません。モダンブラウザ向けにpadding-hackテクニックを置き換えます。画像や動画を扱う場合は、メディアがスペースをどのように埋めるかを制御するためにobject-fitと組み合わせます。flexboxやgridコンテキストでは、計算された寸法に影響を与える可能性のある自動サイズ調整の相互作用に注意してください。

よくある質問

いいえ。aspect-ratioプロパティは、少なくとも一方の次元がautoの場合にのみ有効になります。widthとheightの両方を明示的な値に設定した場合、それらの寸法が優先され、aspect-ratio宣言は完全に無視されます。

aspect-ratio: auto 4 / 3のようなフォールバック比率を持つaspect-ratioを設定すると、画像が読み込まれる前にブラウザがスペースを確保できます。最良の結果と最小限のレイアウトシフトを得るには、img要素に明示的なwidth属性とheight属性も含めて、ブラウザがその固有の寸法をすぐに認識できるようにします。

すべてのモダンブラウザでは、はい。aspect-ratioプロパティは、Chrome、Firefox、Safari、Edgeでサポートされています。padding-bottomハックを維持する唯一の理由は、aspect-ratioをまったくサポートしていないInternet Explorerをサポートする必要がある場合です。

Flexboxアイテムはデフォルトでmin-height: autoを持っており、要素がコンテンツの高さより小さく縮小するのを防ぐことができます。flexアイテムにmin-height: 0を設定して、aspect-ratioで制約された高さが尊重されるようにします。また、flex-growまたはflex-shrinkがaspect-ratioが依存する幅を上書きしていないことを確認してください。

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay