CSS aspect-ratioプロパティの使い方、レスポンシブやレイアウトシフトで大活躍
Post on:2021年2月16日
先月アップデートされたChrome 88でaspect-ratioプロパティがサポートされ、FirefoxとSafariでもまもなくサポートされる予定となっています。
名前の通り、アスペクト比を定義できるCSSのプロパティですが、Webページやスマホアプリで実際にどのように使用すると便利なのか、その使い方を紹介します。
New aspect-ratio CSS property supported in Chromium, Safari Technology Preview, and Firefox Nightly
by Una Kravets
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- アスペクト比とは
- object-fitプロパティ
- 古いハック: padding-topでアスペクト比を保つ
- aspect-ratioでアスペクト比を保つ
- aspect-ratioの実装例: グリッドの一貫性
- aspect-ratioの実装例: レイアウトシフトの防止
- ボーナス: aspect-ratioのためのimageの属性
- 終わりに
アスペクト比とは
アスペクト比は一般的に、幅:高さ、x:yのように異なる次元を2つの整数とコロンで表されます。写真画像でよく使用されるアスペクト比は4:3や3:2で、動画では16:9がよく使用されています。
写真画像でよく使用されるアスペクト比
上記の写真画像はどちらも同じ2:3のアスペクト比です。
レスポンシブデザインの登場により、特に画像のサイズが異なり、使用可能なスペースに基づいて要素のサイズを変化させるためにアスペクト比を維持することはWebデベロッパーにとってますます重要になってきています。
- レスポンシブ対応のiframeを作成し、親の幅を100%にし、高さを特定のビューポート比のままにする。
- 画像・動画用にプレースホルダーコンテナを用意し、その要素がロードされてスペースを占めるときに再レイアウトされないようにする。
- インタラクティブなデータビジュアライゼーションやSVGアニメーション用のレスポンシブなスペースの作成。
- カードやカレンダーなど、複数要素のコンポーネント用のレスポンシブなスペースの作成。
- サイズが異なる複数の画像用のレスポンシブなスペースの作成(object-fitと併用可能)。
object-fitプロパティ
アスペクト比を使用することで、レスポンシブなコンテキストでメディアのサイズを決定するのが便利になります。この記事のもう一つのポイントはobject-fitプロパティで、ブロック内のオブジェクト(画像など)がそのブロックをどのように埋めるべきかを定義できます。
object-fitプロパティで画像をどのように配置すべきか定義できます。
参考: object-fitの使い方: レスポンシブ対応、動画や画像をブラウザいっぱいに表示するCSSのテクニック
object-fitプロパティの値initialとfillは、スペースを埋めるように画像を再調整します。上記の例ではピクセルが再調整されるため、画像はつぶれてぼやけています。これは理想的ではありません。
object-fit: cover;は画像の最小サイズを使用してスペースを埋め、そのサイズに基づいて画像をトリミングして合わせます。ズームインと同じです。
object-fit: contain;は画像全体が表示されるようにするため、coverとは逆に最大サイズ(上記の例では幅)を使用して、スペースに収まるようにアスペクト比を維持します。
object-fit: none;は、画像の元のサイズまま中央(デフォルトの位置)にトリミングされます。
理想的なのは
object-fit: cover;は、さまざまなサイズの画像を扱う時に便利ですが、画像の一部(長い方の両端)が失われてしまいます。
その失われる箇所が重要な場合、重要なコンテンツがトリミングされることを許容することはできません。そのため、理想的なシナリオはトリミングせずにUIスペースに収まるさまざまなサイズのレスポンシブ画像です。
古いハック: padding-topでアスペクト比を保つ
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%;
アスペクト比の値が分かれば、あとは親コンテナに適用するだけです。コードで見てみましょう。
1 2 3 |
<div class="container"> <img class="media" src="..." alt="..."> </div> |
親コンテナにpadding-topを加え、計算した値を定義します。
1 2 3 4 5 6 7 8 9 10 |
.container { position: relative; width: 100%; padding-top: 56.25%; /* 16:9 Aspect Ratio */ } .media { position: absolute; top: 0; } |
aspect-ratioでアスペクト比を保つ
残念ながら、padding-topを使用したハックは直感的ではありません、56.25%が16:9であることは知っている人にしか分かりません。しかも追加の上書きと配置が必要になります。
今の実装方法は、aspect-ratioプロパティでアスペクト比を定義します。
aspect-ratioで、画像のアスペクト比を1:1に設定
前述のCSSで、padding-top: 56.25%;をaspect-ratio: 16 / 9;に置き換え、画像のアスペクト比を保つことができます。
1 2 3 4 |
.container { width: 100%; padding-top: 56.25%; } |
1 2 3 4 |
.container { width: 100%; aspect-ratio: 16 / 9; } |
padding-topの代わりに、aspect-ratioを使用する方が分かりやすく、paddingプロパティをオーバーホールして通常の範囲外のことをすることもありません。
この新しいプロパティは、アスペクト比をautoに設定する機能も追加されました。アスペクト比を持つ要素は、そのアスペクト比を使用します。それ以外の場合、ボックスには優先アスペクト比はありません。
autoと<ratio>の両方を一緒に指定した場合、固有のアスペクト比を持つ要素でない限り、優先されるアスペクト比は幅を高さで割った指定された比率になります。
aspect-ratioの実装例: グリッドの一貫性
このテクニックは、CSS GridやFlexboxなどで非常にうまく機能します。スポンサーアイコンのグリッドのように、アスペクト比を保ちたい子要素があるリストで見てましょう。
1 2 3 4 5 6 7 8 |
<ul class="sponsor-grid"> <li class="sponsor"> <img src="..." alt="..."/> </li> <li class="sponsor"> <img src="..." alt="..."/> </li> </ul> |
1 2 3 4 5 6 7 8 9 10 |
.sponsor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } .sponsor img { aspect-ratio: 1 / 1; width: 100%; object-fit: contain; } |
グリッド内の子要素をさまざまな同じアスペクト比で同時に表示します。
aspect-ratioの実装例: レイアウトシフトの防止
aspect-ratioプロパティのもう一つの優れた機能はプレースホルダーのスペースを作成して、レイアウトシフトを防ぎ、より良いWebバイタルを提供できることです。
レイアウトシフトとは、ページをロードした時にレイアウトがシフトする(ずれる)ことです。
アスペクト比が設定されていない場合に発生するレイアウトシフト
aspect-ratioプロパティを使用すると、このレイアウトシフトを防ぐためのプレースホルダーを簡単に作成できます。
1 2 3 4 |
img { width: 100%; aspect-ratio: 8 / 6; } |
アスペクト比が設定されていると、下記のようにレイアウトシフトを防止できます。
ボーナス: aspect-ratioのためのimageの属性
画像のアスペクト比を設定するもう一つの方法は、imageの属性を使って設定することです、画像のサイズが事前に分かっている場合は、そのサイズをwidthとheightとして設定することをお勧めします。
上記の例では、サイズが800 x 600であることが分かっているので、その場合の画像のマークアップは<img src="image.jpg" alt="..." width="800" height="600">になります。
もし画像のアスペクト比が同じであっても、正確なピクセル値である必要がない場合は、imageの属性値で比率を設定し、画像が適切なスペースを占めるようにCSSのwidth: 100%;を組み合わせて使用します。
コードは、下記の通りです。
1 |
<img src="image.jpg" alt="..." width="8" height="6"> |
1 2 3 |
img { width: 100%; } |
このコードは、CSSでaspect-ratioを画像に設定しているのと同じ効果で、レイアウトシフトが回避されます。
デモページ
終わりに
CSSの新しいプロパティaspect-ratioを使用すると、複数のモダンブラウザでメディアやコンテナに適切なアスペクト比を維持することが簡単になります。
Photo by
- Amy Shamblen via Unsplash
- Lionel Gustave via Unsplash
sponsors