gazou-compressor.jp

背景画像のレスポンシブ設計:CSS image-set() / aspect-ratio / object-fit の最短実装

背景画像は CSSの都合srcset/sizes が使えないため、実装を誤ると 「解像度不足」「容量過大」「表示時に押し下げ(CLS)」のどれかでつまずきます。結論はimage-set() + aspect-ratio + breakpoint切替の三点セット。意味のある画像は<img>へ寄せるのが近道です。

先に結論(型を決めて自動化)
  • 役割で分岐:内容を伝える画像は <img>、純装飾は CSS 背景。
  • 予約サイズ:aspect-ratiomin-height を先出し( CLSゼロ設計 参照)。
  • image-set():AVIF/WebP/JPEG を 1x/2x で宣言。解像度差は breakpoint で差し替え

要点(TL;DR)

1. なぜ image-set() なのか

CSS 背景は srcset/sizes が無く、ブラウザは画面のピクセル密度(dppx)だけを見て候補を選びます。 そのため幅に応じた候補メディアクエリで差し替える必要があります。 また、CLS防止のために予約サイズを先に確保するのが定石です。

2. 最短フロー(実務)

  1. まず意味の有無で分岐(装飾なら背景、内容なら<img>)。アクセシビリティ/SEOの基礎です。
  2. 背景は aspect-ratio(または min-height)で予約サイズを確保し、 image-set() に AVIF/WebP/JPEG を順に並べます。
  3. 画面幅に応じて @media (min-width: …) で候補群を差し替えます(CSS は dppx 想定のため)。
  4. LCP 候補の背景は、代表的に採用されやすい 1枚を <link rel="preload" as="image"> で先読み(やりすぎ注意)。

3. 実装レシピ(コピペOK)

3.1 マークアップ(装飾としての背景)

// HTML<!-- 意味のない装飾なら CSS 背景。アクセシビリティ上は aria-hidden を付与 -->
<div class="hero" aria-hidden="true">
  <div class="hero__inner">
    <h1>見出し</h1>
    <p>キャッチコピー</p>
  </div>
</div>

3.2 CSS:image-set() + aspect-ratio

// CSS/* 背景ヒーロー:aspect-ratio で予約サイズ。背景は cover / center でトリミング */
.hero {
  aspect-ratio: 16 / 9;
  min-height: 42vh;                 /* 端末縦が極端に小さい場合の保険 */
  background-color: #e5e7eb;        /* 先に塗っておくと初期フレームが安定 */
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;

  /* まずは JPEG をフォールバックとして指定(旧ブラウザ保険) */
  background-image: url("/images/hero-800.jpg");

  /* 次に image-set() で AVIF/WebP の候補を載せる(1x/2x) */
  background-image: image-set(
    url("/images/hero-800.avif") type("image/avif") 1x,
    url("/images/hero-1600.avif") type("image/avif") 2x,
    url("/images/hero-800.webp") type("image/webp") 1x,
    url("/images/hero-1600.webp") type("image/webp") 2x,
    url("/images/hero-800.jpg") type("image/jpeg") 1x,
    url("/images/hero-1600.jpg") type("image/jpeg") 2x
  );
}

/* デスクトップではもう一段解像度を上げる(CSSは“dppxベース”なので breakpoint で差し替える) */
@media (min-width: 1024px) {
  .hero {
    background-image: url("/images/hero-1200.jpg");
    background-image: image-set(
      url("/images/hero-1200.avif") type("image/avif") 1x,
      url("/images/hero-2400.avif") type("image/avif") 2x,
      url("/images/hero-1200.webp") type("image/webp") 1x,
      url("/images/hero-2400.webp") type("image/webp") 2x,
      url("/images/hero-1200.jpg") type("image/jpeg") 1x,
      url("/images/hero-2400.jpg") type("image/jpeg") 2x
    );
  }
}

.hero__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: 4rem 1rem;
  color: #111827;
  text-shadow: 0 1px 0 rgba(255,255,255,.6);
}

3.3 LCP候補ならプリロード

// HTML<!-- LCP候補の背景画像(代表的に採用されやすい1枚)を先読み -->
<link rel="preload" as="image" href="/images/hero-1200.avif" type="image/avif">

3.4 意味のある画像は <img> + object-fit

// HTML + CSS<!-- 意味のある画像(alt が必要)なら <img> で表現し、object-fit でカバー -->
<figure class="hero-img">
  <img
    src="/images/hero-1200.avif"
    srcset="/images/hero-800.avif 800w, /images/hero-1200.avif 1200w, /images/hero-1600.avif 1600w"
    sizes="(min-width: 1024px) 1000px, 92vw"
    width="1600" height="900"
    alt="製品の利用シーン"
    fetchpriority="high"
    decoding="async"
  />
  <figcaption class="sr-only">製品の利用シーンの写真</figcaption>
</figure>

<style>
.hero-img { aspect-ratio: 16 / 9; }
.hero-img > img { width: 100%; height: 100%; object-fit: cover; }
</style>

3.5 Next.js 15 での推奨(意味のあるヒーロー)

// TSX (Next.js)// Next.js 15:意味のあるヒーロー画像は next/image を推奨
// 注意: 背景装飾には <div style=background-image> が適任です
/*
import Image from "next/image";

export default function Hero() {
  return (
    <div className="relative" style={{ aspectRatio: "16/9" }}>
      <Image
        src="/images/hero-1600.avif"
        alt="製品の利用シーン"
        fill
        sizes="(min-width: 1024px) 1000px, 92vw"
        priority
      />
    </div>
  );
}
*/

4. 応用と使いどころ

5. 公開前チェック

// Checklist# 公開前チェック(背景画像)
- 役割の切り分け:意味のある画像は <img> / 装飾は CSS 背景
- 予約サイズ:aspect-ratio または min-height で CLS を防止
- image-set():1x/2x & AVIF/WebP/JPEG の順に宣言(先に JPEG を url() で保険)
- breakpoint:モバイルとデスクトップで背景の候補群を切り替え
- LCP:ヒーローが背景なら代表サイズを <link rel="preload"> で先読み
- 画質と容量:/compare で劣化を確認、/compressor でサイズ目安を満たす

6. まとめ

背景は image-set() + aspect-ratio + breakpoint差し替えの型を決めてしまえば運用が楽です。 重要画像は <img> で最短に配信、装飾は CSS 背景で“崩れない見え”に。最後は /compare /compressor で仕上げを確認しましょう。

FAQ(よくある質問)

画像形式の基本方針は?(写真/スクショ/透過)
写真は AVIF / WebP(画質80–85%目安)、UIやスクショはPNG / WebP Lossless、単色ロゴはSVGが基本です。 実装の詳細は srcset/sizes設計ガイド スクショ最適化 を参照してください。
圧縮しても画質を落とさないコツは?
実表示幅に合わせたリサイズ → 過大ダウンロードを防ぎ、srcset/sizes を 実描画幅に一致させます。画質は写真で 80–85% を起点に、ノイズやエッジを目視確認。 仕上げは /compare で Before/After を見比べるのがおすすめです。
CLSを悪化させない画像の置き方は?
すべての画像に width/height(または親に aspect-ratio)を与え、広告・埋め込みは 予約サイズを先に確保します。詳しくは CLSゼロ設計ガイド を参照。

公開:2025-08-31

gazou-compressor.jp 編集部

画像圧縮・変換・背景除去などの実践テクニックと、Webで“速く・軽く・崩さない”ためのノウハウを発信しています。

関連記事