【CSS】縦横比を維持してレスポンシブに画像を表示する方法

【CSS】縦横比を維持してレスポンシブに画像を表示する方法 HTML/CSS

画像を横幅いっぱいに広げつつ縦横比を崩さない表示は、もっとも頻出のレイアウト要件です。結論から言うと「img 要素は CSS で max-width:100%height:auto を指定」「CLS 対策に実寸の widthheight 属性を付ける」「トリミングが必要ならコンテナに aspect-ratioobject-fit」の三点を押さえれば実務はほぼ解決します。以下で用途別の最小レシピを示します。

基本形:縦横比を保ったまま横幅にフィットさせる

最小の実装はこれだけです。画像は親要素の幅に合わせて縮小され、縦横比は自動的に維持されます。

<img src="/images/hero.jpg" alt="サンプル" width="2400" height="1350">
img {
  display: block;          /* 余白のズレ回避 */
  max-width: 100%;         /* 親の幅まで拡大/縮小 */
  height: auto;            /* 比率維持 */
}

widthheight 属性に実寸を入れると、ブラウザは読み込み前からアスペクト比を把握し、コンテンツレイアウトシフト(CLS)を防げます。CSS のサイズ指定と競合しないので必ず付与します。

トリミングして見せたいとき:コンテナ固定比率+object-fit

サムネイルやカードで「常に16:9で切り抜く」といった要件では、ラッパーに比率を与え、内側の画像をはみ出し許容で敷き詰めます。

<figure class="thumb">
  <img src="/images/thumb.jpg" alt="サムネイル" width="1600" height="1200">
</figure>
.thumb {
  aspect-ratio: 16 / 9;    /* 比率を固定 */
  overflow: hidden;         /* 余りを隠す */
  border-radius: 12px;      /* 任意の装飾 */
}
.thumb > img {
  width: 100%;
  height: 100%;
  object-fit: cover;        /* はみ出し前提でトリミング */
}

トリミングせず全体を収めたい場合は object-fit: contain; にします。余白が出るので背景色で調整します。

aspect-ratio が使えない古い環境へのフォールバック

旧ブラウザに配慮する場合は昔ながらのパディングハックで比率を作れます。親の幅に対するパディングの割合で高さを決める仕組みです。

<div class="ratio r-16x9">
  <img src="/images/thumb.jpg" alt="thumb" width="1600" height="900">
</div>
.ratio {
  position: relative;
  width: 100%;
}
.r-16x9 { padding-top: 56.25%; }   /* 9 / 16 = 0.5625 */
.ratio > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

WordPress や記事サイトでの実践ポイント

エディタが吐き出す img には widthheight が入っているはずです。テーマ側で img{max-width:100%;height:auto} を指定しておけば、本文画像は素直にレスポンシブ化されます。アイキャッチをカードで均一に見せたいときは、カード内のラッパーに aspect-ratioobject-fit を組み合わせるのが安全です。

解像度最適化:srcset と sizes の最小例

表示幅に応じて適切な解像度を配信するとデータ量を抑えられます。幅ベースの srcset とメディアクエリでの sizes 指定が基本です。

<img
  src="/images/hero-1200.jpg"
  srcset="/images/hero-600.jpg 600w, /images/hero-1200.jpg 1200w, /images/hero-2000.jpg 2000w"
  sizes="(max-width: 768px) 100vw, 1200px"
  alt="ヒーロー"
  width="2000" height="1125">

画像自体の縦横比はそのまま、ブラウザが最適なファイルを選んで読み込みます。LCP 改善に直結します。

背景として敷く場合と img の使い分け

単なる装飾として敷き詰めたいなら CSS の background-imagebackground-size: cover; が扱いやすく、内容として意味のある写真は必ず <img> を使って alt を適切に入れます。アクセシビリティ上の選択が重要です。

.hero {
  aspect-ratio: 21 / 9;
  background: center / cover no-repeat url("/images/hero.jpg");
}

縦長・横長が混在するギャラリーの均一表示

モザイク崩れを防ぐには、枠の比率を固定し、各画像は object-fit: cover で収めます。これで縦横比がバラバラでもカードの高さが揃います。

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.grid figure { aspect-ratio: 4 / 3; overflow: hidden; }
.grid img { width: 100%; height: 100%; object-fit: cover; display: block; }

CLS とパフォーマンスの仕上げ

画像には必ず実寸の widthheight を付けて比率スロットを確保し、レイジーロードを使う場合はヒーロー画像だけは loading="eager" にして早期描画を促します。長い記事ではフォールド下の画像に loading="lazy" を付けます。これらは縦横比の維持とともに実測の体感速度を大きく左右します。

まとめの最小テンプレート

もっとも汎用的な組み合わせは、本文画像は img{max-width:100%;height:auto}、カードやサムネはコンテナに aspect-ratioobject-fit:cover を適用、そしてすべての img に実寸の widthheight を付ける、の三点です。これだけで縦横比の破綻、カードの高さ不揃い、CLS の悪化を同時に解消できます。