Chromium、Safari Technology Preview、およびFirefox Nightlyでサポートされる新しいアスペクト比のCSSプロパティ
レスポンシブレイアウトの間隔を維持するのに役立つ新しいCSSプロパティ。
アスペクト比 #
アスペクト比は、2 つの整数とコロンを使って「幅:高さ」または 「x:y」の次元として表されるのが最も一般的です。写真の最も一般的なアスペクト比は 4:3 と 3:2 ですが、ビデオや最近のコンシューマー向けカメラのアスペクト比は 16:9 である傾向があります。
レスポンシブデザインが出現したことで、特に画像のサイズと要素のサイズが使用可能なスペースに基づいて変化するようになったため、アスペクト比を維持することが Web 開発者にとってますます重要になっています。
アスペクト比の維持が重要になる場合には、以下の例があります。
- 親の幅の100%であり、高さが特定のビューポート比のままであるレスポンシブ iframe を作成する
- 画像、動画、または埋め込みが読み込まれてスペースを占有するときに再レイアウトされないように、各アイテム用の固有のプレースホルダーコンテナを作成する
- インタラクティブなデータ視覚化または SVG アニメーション用に均一でレスポンシブなスペースを作成する
- カードやカレンダーの日付といった複数の要素が伴うコンポーネント用に均一でレスポンシブなスペースを作成する
- サイズの異なる複数の画像用に均一でレスポンシブなスペースを作成する(
object-fitとともに使用する)
Object-fit #
アスペクト比を定義すると、レスポンシブなコンテキストでメディアのサイズを決定するのに役立ちます。このバケツのもう 1 つのツールは、object-fit プロパティです。ユーザーはこれを使用して、ブロック内のオブジェクト(画像など)がそのブロックをどのように埋めるかを記述できます。
object-fit の値を実演。Codepen のデモをご覧ください。initial 値と fill 値は、スペースを埋めるように画像を再調整します。この例では、これにより、ピクセルが再調整されるにつれ、画像が押しつぶされてぼやけています。これは理想的ではありません。object-fit: cover は、画像の最小サイズを使用してスペースを埋め、このサイズに基づいて画像をトリミングしてフィットさせます。最も低い境界で「ズームイン」します。object-fit: contain は、画像全体が常に表示されるようにするため、 cover の動作とは逆に、最大の境界のサイズ(上記の例では幅)を取って、画像のサイズを変更して固有のアスペクト比を維持しながらスペースにフィットさせます。object-fit: none の場合は、中央(デフォルトのオブジェクト位置)で自然なサイズでトリミングされた画像を示します。
object-fit: cover は、サイズの異なる画像を処理する場合に、ほとんどの状況で、均一なインターフェイスを確保するように機能する傾向がありますが、この方法では情報が失われます(画像は最も長い辺に沿ってトリミングされます)。
これらの失われる情報が重要であるならば(美容製品のフラットレイで作業する場合など)、重要なコンテンツをトリミングすることは許容できません。したがって、トリミングせずに UI スペースにフィットするさまざまなサイズのレスポンシブ画像が理想的と言えます。
以前の技法: padding-top でアスペクト比を維持する #
padding-top を使用して、カルーセル内のプレビュー後の画像に 1:1 のアスペクト比を設定する。これらをさらにレスポンシブにするために、アスペクト比を使用できます。これにより、特定の比率のサイズを設定し、残りのメディアを個々の軸(高さまたは幅)に基づいて設定できます。
画像の幅に基づいてアスペクト比を維持するために現在広く受け入れられているクロスブラウザソリューションは、「Padding-Top ハック」として知られています。このソリューションには、親コンテナと絶対的に配置された子コンテナが必要です。その上で、アスペクト比をパーセント率として計算し、 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 のアスペクト比 */
}
.media {
position: absolute;
top: 0;
}
aspect-ratio でアスペクト比を維持する #
aspect-ratio を使用してカルーセル内のプレビュー後の画像に 1:1 のアスペクト比を設定する残念ながら、これらの padding-top 値の計算はあまり直感的ではなく、追加のオーバーヘッドと配置が必要です。新しい固有の aspect-ratio CSS プロパティを使用すると、アスペクト比を維持するための言語がはるかに明確になります。
同じマークアップで、padding-top: 56.25% をaspect-ratio: 16 / 9 に置き換え、aspect-ratio を指定された width / height の比率に設定します。
Using padding-top
```css .container { width: 100%; padding-top: 56.25%; } ```Using aspect-ratio
.container {
width: 100%;
aspect-ratio: 16 / 9;
}
padding-top の代わりに aspect-ratio を使用する方がはるかに明確であり、padding プロパティをオーバーホールして通常の範囲外のことを行うことがありません。
この新しいプロパティは、アスペクト比を auto に設定する機能も追加します。この場合、「固有のアスペクト比で置き換えられた要素はそのアスペクト比を使用しますが、そうでない場合は、ボックスには優先アスペクト比はありません」。 auto と <ratio> の両方が同時に指定されている場合、優先アスペクト比は、width を height で除算した指定の比率です。ただし、両方が一緒に指定されている場合、固有のアスペクト比で置き換えられた要素である場合は、代わりにそのアスペクト比が使用されます。
例: グリッドの一貫性 #
これは、CSS Grid や 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;
}
例: レイアウトシフトを防止する #
aspect-ratio のもう 1 つの優れた機能は、プレースホルダースペースを作成して、累積レイアウトシフトを防止し、より優れたウェブバイタルを提供できることです。この最初の例では、Unsplash などの API からアセットを読み込むと、メディアの読み込みが終了したときにレイアウトシフトが作成されます。
一方で、aspect-ratio を使用すると、このレイアウトシフトを防止するためのプレースホルダーが作成されます。
img {
width: 100%;
aspect-ratio: 8 / 6;
}
ボーナスヒント: アスペクト比の画像属性 #
画像のアスペクト比を設定するもう 1 つの方法は、画像の属性を使用することです。前もって画像のサイズがわかっている場合、これらのサイズをその width と height で設定するのがベストプラクティスとされています。
上記の例では、サイズが 800 x 600px であることがわかっている場合、画像のマークアップは、<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%;
}
最終的な効果は、CSS を介して画像に aspect-ratio を設定する場合と同じで、累積的なレイアウトシフトが回避されます(Codepen のデモをご覧ください)。
まとめ #
複数の最新のブラウザに導入される新しい aspect-ratio CSS プロパティを使用すると、メディアとレイアウトのコンテナの適切なアスペクト比を、もう少し簡単に維持できるようになります。
写真提供: Amy Shamblen および Lionel Gustave(Unsplash より)