👻

【CSS】画像のアスペクト比を維持する方法あれこれ

2025/01/26に公開

ウェブサイトに画像を配置するとき、縦横比が崩れて不自然に見えてしまった経験はありませんか?

PC、スマホ、タブレットなど、さまざまな端末の画面サイズに応じて画像を拡大・縮小するのはよくある課題です。本記事では、その解決方法をメモがてら整理してみたいと思います。

画像のサイズがわからない場合

ユーザーがアップロードしたサイズがランダムな画像を表示する場合などを想定しています。
この場合は、以下のようなコードで対応できます。

やっていることを簡単に説明すると、画像の幅を親要素の幅に合わせ、高さは自動で調節するということです。

幅が指定されることにより、はみ出しを防ぐことができます。

<div class="image-container">
  <img src="画像のパス" alt="サンプル画像">
</div>
.image-container {
  max-width: 100%; /* コンテナの最大幅を設定(任意) */
  overflow: hidden; /* 必要に応じてはみ出した部分を隠す */
  
  img {
    width: 100%; /* 画像の幅を親要素に合わせる */
    height: auto; /* 縦横比を維持する */
    display: block;  /* インライン要素の隙間を防ぐ */
  }
}

画像のサイズが分かっている場合

バナー画像を設置する場合のような、画像のサイズがわかっている場合は、
CSSでその縦横比を指定して、画面幅に応じて拡大・縮小する方法をとれます。

aspect-ratioプロパティの使用

aspect-ratioプロパティとは、要素のアスペクト比(縦横比)を指定するプロパティです。
幅 / 高さ という形で指定し、例えば aspect-ratio: 16 / 9; と設定すれば、
要素が16:9の比率を保ちながらサイズを調整します。

ただし、注意点として、高さや幅が固定値で指定されている場合、その固定値が優先されてしまい、aspect-ratioで指定した比率が無効になることがあります。たとえば、height: 300px;と指定した要素に aspect-ratio: 16 / 9;を設定しても、固定された高さが適用されるため比率が崩れる可能性があります。

そのため、aspect-ratioを活用する際には、高さや幅の固定値を避け、widthまたはheightのどちらかを柔軟に設定するのが一般的です。
※以下のコードでも、固定値で幅や高さを指定していないです。

<div class="image-container">
  <img src="画像のパス" alt="サンプル画像">
</div>
.image-container {
  max-width: 100%; /* 画面幅を超えないようにする */
  overflow: hidden; /* 必要に応じてはみ出た部分を隠す */

  img {
    aspect-ratio: 600 / 319; /* 元画像の縦横比を維持 */
    width: 100%; /* 親要素の幅に合わせる */
    height: auto; /* 自動で高さを調整 */
    display: block; /* インライン要素の隙間を防ぐ */
  }
}

アスペクト比を使って高さを計算する方法

aspect-ratioを使うのとほぼやっていることは変わらないのですが、
アスペクト比を元に高さを指定する方法もあります。

<div class="image-container">
  <img src="画像のパス" alt="サンプル画像">
</div>
.image-container {
  max-width: 100%; /* 画面幅を超えないようにする */
  overflow: hidden; /* 必要に応じてはみ出た部分を隠す */

  img {
    width: 100%; /* 親要素の幅に合わせる */
    height: calc(100% * (319 / 600)); /* 正確な縦横比に基づいた高さ計算 */
    display: block; /* インライン要素の隙間を防ぐ */
  }
}

高さの計算式は、100%(親要素の幅のpx数を指す) * (画像の高さ / 画像の幅)です。
高さが幅に占める割合を計算し、それを幅に掛け算することで高さを算出しています。

※親要素の幅が1200pxとします。
この場合、1200px * 319 / 600 = 638pxが幅となります。
アスペクト比のそれぞれを2倍した幅並びに高さになっており、正確な計算結果とわかります。

画像のサイズが分かっている場合、どちらを使うべきか

モダンな書き方はaspect-ratioになります。

IEや昔のsafariで対応していなかったプロパティですが、
現在は主要なブラウザのすべてで対応しているので、使えない理由がなければこちらを使えば問題ないかと思います。
(親要素の高さや幅を固定値で指定している場合や、何か理由があって特別な計算が必要な場合などを除けばこちらで良いと思います。)

Discussion