HTML 要素の縦横比を CSS だけで固定したいときってありませんか?レスポンシブウェブデザインが主流になった現在ならなおさらです。aspect-ratio プロパティを使えば簡単に実現できます。SEO 界隈でも話題になっている CLS(Cumulative Layout Shift)対策にも役に立ちます。今回は aspect-ratio プロパティの使い方について解説します。
使い方
具体的な使い方を見た方が手っ取り早く理解できますので、まずは次の HTML サンプルをご覧ください。
<div class="row">
<div class="col violet">あいうえお。</div>
<div class="col lime">かきくけこ。さしすせそ。たちつてと。</div>
<div class="col cyan">なにぬねの。</div>
<div class="col orange">はひふへほ。</div>
</div>
内側の 4 つの div 要素のブロックを均等な幅で横に並べるとしましょう。そこでまず思いつくのが、次の CSS です。
.row {
display: flow-root;
}
.col {
float: left;
width: 25%;
}
確かに横に均等に並びますが、高さが均等になりません。
では、それぞれのカラムの縦横比を固定にして、高さを合わせてみましょう。もし中のテキストがはみ出すようなら、その部分は非表示にして、強制的に指定の縦横比を維持することにします。
.col {
float: left;
width: 25%;
aspect-ratio: 4 / 3;
overflow: hidden;
}
これで、ブラウザーウィンドウの幅を変更しても、それぞれのブロックの縦:横の比率は 4:3 で維持されます。
もっとレスポンシブにグリッドレイアウトで行くなら、次のような感じでしょうか。この例は aspect-ratio プロパティの規定が記載された仕様書 W3C CSS Box Sizing Module Level 4 のサンプルを筆者がアレンジしたものです。
<ul>
<li class="violet">あいうえお。</li>
<li class="lime">かきくけこ。さしすせそ。たちつてと。</li>
<li class="cyan">なにぬねの。</li>
<li class="orange">はひふへほ。</li>
</ul>
ul {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(12em, 1fr));
}
li {
aspect-ratio: 2/1;
overflow: auto;
}
aspect-ratio プロパティに指定可能な値
この aspect-ratio には縦横比を「横 / 縦」という形式で指定します。横:縦の比率が 4:3 にしたいなら、8 / 6 でも 1024 / 768 でも構いません。
aspect-ratio: 1024 / 768;
また、縦の比率を省略することも可能です。その場合、縦の比率は 1 と解釈されます。横:縦の比率が 2:1 なら、2 と指定しても構いません。
aspect-ratio: 2;
もう一つ指定可能な値があります。それは auto です。これは aspect-ratio プロパティのデフォルト値(初期値)です。auto の挙動はちょっと複雑ですが、簡単に解説します。
aspect-ratio: auto;
まず自然縦横比(natural aspect ratio)を持つ要素の場合は、その要素自身が持つ縦横比が適用されます。自然縦横比を持つ要素とは、その要素自身に固有のサイズがあり縦横比が確定する要素のことです。
具体的には img 要素やvideo 要素のようにリソースが読み込まれたら縦の長さと横の長さが確定する要素が該当します。そのほか、SVG も該当します。SVG は絶対的な長さが確定しないものもありますが、少なくとも縦横比は決まります。
もし自然縦横比を持たない要素の場合は、縦横比は持ち合わせない、と解釈されます。つまり、前述の aspect-ratio プロパティを使用しなかった場合の div 要素のように、状況に合わせて縦横比が変わります。実際には高さが流動的になります。
auto の意味を言葉で説明すると、とても難しく感じますが、ある意味、直感的な挙動ですよね。そして、aspect-ratio プロパティは、あらゆる HTML 要素に対して img 要素のようなレイアウト特性を与える、とも解釈できます。
なお、縦横比の計算結果が 0 または無限大になってしまった場合は、auto として処理されます。たとえば、0 / 2 や 2 / 0 と指定した場合ですね。
CLS(Cumulative Layout Shift)対策にも便利
CLS(Cumulative Layout Shift)とは、ページのロード中にコンテンツの位置がずれる(シフトする)現象のことです。
例えば、ページ内に width 属性と height 属性を指定していない img 要素が存在するとしましょう。そして、その読み込む画像のファイルサイズが大きいとします。もし回線速度が遅いユーザーがそのページにアクセスをすると、まずテキストが先にレンダリングされます。その後、ユーザーがそのテキストを読んでいる途中で画像の読み込みが完了してレイアウトが下にずれる、といった現象が発生します。このようなリソースが積み重なると、読みたいテキストの位置がどんどん下にずれていきます。近年は広告が悪さをして CLS が発生するサイトをときどき見かけますよね。
読者にとって CLS は不便極まりない現象ですので、可能な限り避けるべきです。Google も、ウェブページの UX の重要指標の一つに CLS を挙げています。詳細は「Core Web Vitals」というコンセプトを調べてみると良いでしょう。
SEO にどれほど影響するのかは分かりませんが、SEO 界隈では大きな話題になっていました。なぜなら Google Search Console の 「ウェブに関する主な指標」で、 Core Web Vitals の測定結果をもとにした評価が表示されるようになったからです。Google Search Console に表示されるともなれば、SEO に影響するんじゃないかと気にしますよね。
「ウェブに関する主な指標」 は、どうやら Google のロボットに認識されてから 90 日以上経過しないと出てこないようでして、残念ながら、このブログの評価の結果は表示されませんでした。いずれ掲載します。
img 要素に width 属性と height 属性を正しくセットしておけば CLS は発生しませんが、レスポンシブな近年では width 属性と height 属性をセットしないことのほうが多いのではないでしょうか。たとえば、こんな img 要素があったとしましょう。
<img src="pic-small.jpg" alt="" class="aspect">
この img 要素に対して、次の CSS を当てます。
img.aspect {
width: 20%;
aspect-ratio: 400 / 255;
}
実は aspect-ratio プロパティを指定しなくても、この画像はブラウザーウィンドウの横幅に応じてちゃんとレスポンシブです。しかし、aspect-ratio プロパティがないと画像が高さが事前に確定できず、CLS が発生します。aspect-ratio を指定することで、画像が読み込まれる前に高さを確定でき、CLS を防げるのです。
対応ブラウザー
実は、aspect-ratio プロパティは Chrome や Firefox では以前から利用可能でした。しかし、Safari が対応しておらず、ウェブ制作の現場ではなかなか使うことができませんでした。しかし、Safari 15 で aspect-ratio プロパティがサポートされたおかげで、やっとウェブ制作の現場で利用できるようになりました。
現在は主要なブラウザーすべてで aspect-ratioプロパティを利用することができます [Can I use]。
まとめ
aspect-ratio プロパティは誰もが以前から欲しかった機能ではないでしょうか。少なくとも筆者は aspect-ratio プロパティの存在を知ったときは、早くすべてのブラウザーが対応してくれないかと願ったくらいです。しかし、Safari が aspect-ratio をサポートしたことで、やっとそのときが訪れました。これからは遠慮なく aspect-ratio プロパティを使っていこうと思った次第です。
今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。