コーディング中に、「ウィンドウ幅を変えると画像のアスペクト比が変わってしまう」と指摘を受けたことはありますか?
大事な画像や動画が、変なふうに見切れたりしていたら格好付かないですよね。
今回はコーディング初心者さんに向けて、画像のアスペクト比の設定をする方法を、サンプルコードとデモ付きで紹介していきます。
目次
アスペクト比とは
アスペクト比(アスペクトひ、 英語: aspect ratio)は、矩形における長辺と短辺の比率。
引用元:アスペクト比 – Wikipedia
ウィキペディアによると、アスペクト比とは、「矩形における長辺と短辺の比率」とのことでした。
つまり縦横比のことですね。
モニターで言うと、最近の縦横比の主流は16:9や16:10の横長のものです。
動画もモニターに合わせ、16:9で作成されていることが多くなりました。
一眼レフ・ミラーレス一眼などで撮影した写真では、3:2であることが多いようです。
また、昔のテレビ画面や、デジカメで撮影した写真は4:3のかなり正方形に近い形です。
たまに昔のアニメを見ると、画面のアス比が4:3で懐かしいな~と思います。
HTML・CSSコーディングでアスペクト比はどこで使う?
Webデザイン時には、画面サイズを考慮してFVを作成するなど、アスペクト比を意識することも多いかと思います。
HTML・CSSコーディングでは、どのような場合でアスペクト比に気を付けなければならないでしょうか?
主に、2パターンあります。
iframeなどで設置した動画
iframeは、例えばyoutubeだと埋め込み用のコードをコピーするときに、iframeタグにwidthとheightの記述が一緒についてきますよね。
レスポンシブ対応の場合は、widthの値よりもウィンドウ幅が小さくなった時に崩れていってしまうので、邪魔だなと思うかもしれませんが、widthとheightの記述がないと小さく表示されてしまうため設定しておきたいところです。
横幅を100%にしておけばどのウィンドウ幅でも崩れず大きく表示できますが、heightは通常パーセントで設定することができません。height: 300px;のような固定値で設定しておいてもよいですが、横幅はウィンドウ幅に合わせて縮んでいきますが、高さは固定値のまま変わらないので、だんだんとアスペクト比が変わっていってしまいます。
折角動画を埋め込んだのに最適な縦横比・サイズで見れないなら、あまり意味がありません。それならyoutubeで動画を見るほうがよいです。
画像(記事一覧のサムネイルなどの画像)
画像も動画と同様に縦横比を変えたくない要素のひとつです。
今回は、記事一覧のサムネイルを例に上げて紹介していきます。
CMS対応をする場合で、記事のサムネイルにどんな大きさの画像が入ってもいいように、予め画像のエリアを決めておいて、background-size: cover;やobject-fit: cover;で画像を要素のエリアいっぱいに表示させることが多いと思います。
上記のiframeの場合と同様ですが、画像のエリアに、例えばwidth: 100%; height: 300px;と指定しておいたとすると、横幅はウィンドウ幅に合わせて縮んでいきますが、高さは変わらないので、だんだんとアスペクト比が変わっていってしまいますね。
結果、画像の左右が見切れて格好悪いサムネになってしまうのです。
CSSでアスペクト比を設定しよう
アスペクト比の設定方法が2つありますので、次の項目からiframe・記事サムネイルの2パターンで紹介していきます。
01aspect-ratio
aspect-ratioは、ボックスの推奨アスペクト比を設定してくれます。
widthとheightが設定してあると、アスペクト比を上書きしてその値になってしまうので、注意してください。
width: 100%;とaspect-ratioを設定して、要素の幅が変わると自動で高さも変わって、アスペクト比を保ってくれる という使い方が便利そうです。
アスペクト比の設定は以下のようにして行います。
16:9なら、aspect-ratio: 16 / 9;
4:3なら、aspect-ratio: 4 / 3;
正方形(1:1)なら、aspect-ratio: 1 / 1;
参考ドキュメント:aspect-ratio
iframe
今回のデモはyoutube動画を埋め込んでありますが、同じiframe埋め込みのGoogleマップや、videoタグで設置する動画にも応用できます。
サンプルコードは以下です。
単に、iframeの親要素に横幅とaspect-ratio: 16 / 9;を設定して、中のiframeの縦横を100%にするだけで、縦横比を保ったまま縮小してくれます。
直接iframeにaspect-ratio: 16 / 9;・width: 100%;・height: 100%;を設定してもよいです。
今回は、親要素で横幅の最大値を決めたかったので、入れ子の構造にしてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // HTML <div class="iframe-aspect"> <iframe width="560" height="315" src="https://www.youtube.com/embed/bjmBJ1Fl0cs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> </div> // CSS .iframe-aspect { aspect-ratio: 16 / 9; // ★ max-width: 600px; } .iframe-aspect iframe { width: 100%; // ★ height: 100%; // ★ } |
記事サムネイル
よくある記事一覧のサムネイル画像です。SPレイアウトやリキッドレイアウトで、横幅が縮まったときに画像の比率が変わってしまうというのをよく見かけます。
折角設定したサムネイルなので、画像比率が変わって見切れないようにしたいですよね。
サムネイル画像にも、アスペクト比を設定しておきましょう。
iframeと同様に、imgの親要素にaspect-ratio: 16 / 9;を設定しています。
また、中のimgにはobject-fit: cover; width: 100%; height: 100%;で、親要素いっぱいになるようにしました。
これは、サムネイルの推奨アスペクト比は16:9ですが、サムネイルを設定する人が必ず16:9の画像を用意してくれるとも限らないため、違う比率の画像が入っても崩れないように設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // HTML <div class="article-card"> <div class="thumb"> <img src="https://placehold.jp/600x600.png" alt=""> </div> <p class="date">20XX.XX.XX</p> <p class="text">ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</p> </div> // CSS .article-card { max-width: 600px; } .article-card .thumb { aspect-ratio: 16 / 9; // ★ } .article-card .thumb img { object-fit: cover; width: 100%; height: 100%; } .article-card .date { font-size: 14px; font-weight: bold; margin-top: 10px; } .article-card .text { font-weight: bold; margin-top: 10px; } |
aspect-ratioを使う際の注意点
1点だけ、aspect-ratioを使う際の注意点があります。
can I useを見ると、aspect-ratioはiOSのsafariではiOS15~でしか使用できません。
国内のiOS14のシェア率は、2023年2月時点で5.2%ですので、結構多めかなと思います。
iOS14のユーザーを無視できないなら、次で紹介するpadding-topの実装方法を試していただければと思います。
シェア率参考: 最新のiOS バージョン別シェアまとめ
02padding-top
aspect-ratioを利用しない場合は、padding-topでアスペクト比を設定することができます。
有名なハックですが、合わせて紹介していこうと思います。
iframe
iframeのアスペクト比をpadding-topで設定する場合の方法です。
こちらもaspect-ratioを利用する場合と同じく、Googleマップのiframe埋め込みや、videoタグで設置する動画にも応用できます。
padding-topでiframeのアスペクト比を設定するには、iframeに親要素を2つ用意します(aspect-ratioより入れ子が1つ増えます)。
一番上の要素には横幅を指定しておきます。
二番目の要素は、
・iframeをabsoluteするのでposition: relative;
・親要素のmax-widthを基準に100%になるようにwidth: 100%;
・padding-topで高さを取るのでheight: 0;
・最後に、padding-top: 56%;で高さを取ります。
なぜ56%かというと、16:9を基準に横幅(600px)を1としたときの縦幅が0.5625になるため、56%と設定します。
iframeタグは、padding-topで取ったエリアに重なるように、absoluteして縦横を100%で設定します。
具体的な計算方法は以下です。
16:9のアスペクト比の場合、16:9=1:xのxの値を求めると0.5625。
0.5625を百分率に直して0.5625*100で56.25%、小数点を四捨五入して56%となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // HTML <div class="iframe-aspect-padding"> <div class="inn"> <iframe width="560" height="315" src="https://www.youtube.com/embed/bjmBJ1Fl0cs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> </div> </div> // CSS .iframe-aspect-padding { max-width: 600px; } .iframe-aspect-padding .inn { position: relative; width: 100%; // ★ height: 0; // ★ padding-top: 56%; // ★ /* ↑16:9を基準に横幅を1としたときの縦幅が0.5625のため、56% */ } .iframe-aspect-padding iframe { position: absolute; // ★ top: 0; left: 0; width: 100%; // ★ height: 100%; // ★ } |
padding-topの値は、16:9なら56.25%、4:3なら75%と、アスペクト比によって決まっていますので、簡単に設定ができます。
ですが、実際には予め画像比率がわからない場合や、デザインの比率が微妙な値であることも多いため、その場合は計算に便利なサイトを利用してみてください。
縦幅と横幅を入力するだけで、1:xの値を出力してくれます!
比率計算機
記事サムネイル
記事サムネイルのアスペクト比をpadding-topで設定する場合の方法です。方法はiframeの場合とほとんど同じです。
HTMLの構成はaspect-ratioと同じです。
一番上の要素に横幅を指定しておきます。
画像を囲う二番目の要素には、
・imgをabsoluteするのでposition: relative;
・親要素のmax-widthを基準に100%になるようにwidth: 100%;
・padding-topで高さを取るのでheight: 0;
・最後に、padding-top: 56%;で高さを取ります。
計算方法はiframeの解説で詳しく紹介しているので、上記をごらんください。
imgタグは、padding-topで取ったエリアに重なるように、absoluteして縦横を100%で設定します。
また、このままだと入っている画像比率が16:9でない場合に歪むので、object-fit: cover; して、画像をエリアいっぱいにしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // HTML <div class="article-card-padding"> <div class="thumb"> <img src="https://placehold.jp/600x600.png" alt=""> </div> <p class="date">20XX.XX.XX</p> <p class="text">ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</p> </div> // CSS .article-card-padding { max-width: 600px; } .article-card-padding .thumb { position: relative; width: 100%; height: 0; padding-top: 56%; // ★ /* ↑16:9を基準に横幅を1としたときの縦幅が0.5625のため、56% */ } .article-card-padding .thumb img { position: absolute; // ★ top: 0; left: 0; object-fit: cover; // ★ width: 100%; // ★ height: 100%; // ★ } .article-card-padding .date { font-size: 14px; font-weight: bold; margin-top: 10px; } .article-card-padding .text { font-weight: bold; margin-top: 10px; } |
まとめ
今回は要素のアスペクト比の設定について、aspect-ratioとpadding-topを使った場合の方法で紹介しました。
基本的にはaspect-ratioの方が記述が少なく書けますが、iOS15~でないと動作しないので、筆者はまだあまり使わないプロパティです。
iOSの更新がもっと進んでいって、iOS14のシェア率が1%未満くらいになるまでは、まだ使わないかなと思います。
ですが、便利なプロパティのため、スマホ対応が不要な場合や、案件の要件としてiOS14を考慮しなくてよい場合には、ぜひ利用してみてください!