CSSで要素の縦横比を固定するには
aspect-ratio で要素の縦横比を宣言し、幅が変わっても 16:9 や 1:1 の形を保つ基本形を示す。
高さを計算して指定しなくても、幅から高さが自動で決まる。
実行確認済みは、ブラウザで実際に描画して見た目を確認したものである。
公開:
<div class="ratio-row">
<div class="ratio ratio--16x9">16 / 9</div>
<div class="ratio ratio--1x1">1 / 1</div>
</div>.ratio-row {
display: flex;
gap: 12px;
align-items: flex-start;
}
.ratio {
width: 200px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: #0f766e;
color: #fff;
font-weight: 700;
}
.ratio--16x9 {
aspect-ratio: 16 / 9; /* 幅 200px なら高さは 112.5px になる */
}
.ratio--1x1 {
width: 120px;
aspect-ratio: 1 / 1;
}aspect-ratio は「幅と高さの比」を宣言するプロパティで、片方のサイズが決まればもう片方が自動で決まる。
高さを固定値で書くと画面幅が変わったときに形が崩れるため、比を保ちたい要素では高さではなく比を指定する。
つまずき
aspect-ratio を書いたのに効かない場合、まず height が別の場所で指定されていないかを疑うとよい。
aspect-ratio は「サイズが自動で決まる側」を計算するプロパティなので、幅と高さの両方が確定していると比を保つ余地が無く、指定した高さが優先される。
同じ理由で、align-items: stretch のまま flex アイテムに置くと親の高さに引き伸ばされて比が崩れる。
上の例で align-items: flex-start を添えているのはこれを避けるためである。
中身がはみ出すとき
aspect-ratio が決めるのはあくまで推奨サイズで、中身が入り切らなければ要素はその分だけ伸びる。
比を厳密に守りたいときは overflow: hidden を添えるか、min-height: 0 で最小高さの制約を外す。
中に画像を入れる場合は、画像側に width: 100%; height: 100%; object-fit: cover; を与えると、枠の比に合わせて中央を切り抜いて表示できる。
padding-top ハックとの違い
aspect-ratio が使えるようになる前は、padding-top: 56.25% で高さを作り、中身を position: absolute で重ねる手法が使われていた。
パーセント指定の padding が「親の幅」を基準にする性質を利用した回避策で、比の値を自分で百分率へ換算する必要があり、中身も絶対配置に縛られていた。
aspect-ratio は比をそのまま書けて中身の配置も自由なので、新規に書くコードでハックを選ぶ理由はもう無い。