アートディレクション対応のレスポンシブ画像:<picture> / media / type の実務レシピ
1枚のトリミングで全端末を賄うと、見せたい要素が切れたり、小さくなったりします。 そこで使うのが <picture>。モバイル/デスクトップで別トリムを出し分ければ、 ヒーローやサムネの訴求力が上がります。実装は「media → type → srcset/sizes → 予約サイズ → LCP」の順に決めるのが最短です。
先に結論(運用ルール)
- 条件の特殊→一般の順に
<source>
を並べ、最後に<img>
。 - 描画幅に合わせて
sizes
を決め、srcset
は候補解像度。 - LCP候補は preload を1枚だけ。CLSは aspect-ratio で予約。
- 意味のある画像は alt を、装飾は
alt=""
(スクリーンリーダー配慮)。
要点(TL;DR)
<picture>
はトリミング切替とコーデック切替の両方に効く。- 順序はPC条件 → 既定。最後は JPEG の
<img>
を残す。 sizes
は描画幅、srcset
は候補解像度(関連: srcset/sizes設計)。- 予約サイズ(
aspect-ratio
)でCLSゼロ。LCP候補は代表1枚だけ preload(関連: 画像優先度)。
1. なぜ <picture>
が要るのか
単一トリムで srcset/sizes
だけに頼ると、被写体の位置や文字の可読性が損なわれがちです。<picture>
なら“画像そのものを差し替え”られ、配役(被写体の見え方)を端末ごとに最適化できます。
2. 最短フロー(実務)
- トリミング(縦長/横長)を決め、各レイアウトの描画幅を把握。
- 各トリムに対して AVIF/WebP/JPEG の候補と
srcset/sizes
を用意。 - 条件の特殊→一般の順に
<source>
を並べ、最後に<img>
。 - LCP候補は代表1枚だけ
preload
。予約サイズはaspect-ratio
で先出し。
3. 実装レシピ(コピペOK)
3.1 <picture>
の基本構造
// HTML<!-- モバイルは縦長、PCは横長の“別トリム”を配信 -->
<!-- 予約サイズはCSSで先出し(後述)。altは“画像が伝える内容”を簡潔に -->
<picture>
<!-- 1) 先に“より特殊な条件”から書く(上から判定) -->
<!-- Desktop (>=1024px):横長の別トリム -->
<source
type="image/avif"
media="(min-width: 1024px)"
srcset="/hero-wide-1200.avif 1200w, /hero-wide-1600.avif 1600w, /hero-wide-2000.avif 2000w"
sizes="1000px"
/>
<source
type="image/webp"
media="(min-width: 1024px)"
srcset="/hero-wide-1200.webp 1200w, /hero-wide-1600.webp 1600w, /hero-wide-2000.webp 2000w"
sizes="1000px"
/>
<!-- 2) Mobile(既定):縦長の別トリム -->
<source
type="image/avif"
srcset="/hero-tall-600.avif 600w, /hero-tall-900.avif 900w, /hero-tall-1200.avif 1200w"
sizes="92vw"
/>
<source
type="image/webp"
srcset="/hero-tall-600.webp 600w, /hero-tall-900.webp 900w, /hero-tall-1200.webp 1200w"
sizes="92vw"
/>
<!-- 3) 最後に JPEG フォールバック(既定トリムに合わせる) -->
<img
src="/hero-tall-900.jpg"
srcset="/hero-tall-600.jpg 600w, /hero-tall-900.jpg 900w, /hero-tall-1200.jpg 1200w"
sizes="92vw"
width="900" height="1200"
alt="プロダクトを手にするユーザーの写真"
fetchpriority="high"
decoding="async"
/>
</picture>
3.2 CLSゼロ:予約サイズの与え方
// CSS/* CLSゼロ:予約サイズ。ブレークポイント毎に比率が変わるならCSSで切替 */
.hero {
/* 既定(モバイル):縦長 3:4 */
aspect-ratio: 3 / 4;
background: #f3f4f6; /* 初期塗りで安定 */
}
@media (min-width: 1024px) {
.hero { aspect-ratio: 16 / 9; } /* PCでは横長に切替 */
}
3.3 LCP候補なら preload
// HTML<!-- LCP候補の代表画像を preload(<picture> でも有効)。
画像候補と同じ imagesrcset/imagesizes を付けると二重DLを防ぎやすい -->
<link
rel="preload"
as="image"
href="/hero-wide-1600.avif"
imagesrcset="/hero-wide-1200.avif 1200w, /hero-wide-1600.avif 1600w, /hero-wide-2000.avif 2000w"
imagesizes="1000px"
type="image/avif"
/>
3.4 DPR(1x/2x)だけ切り替えたいとき
// HTML<!-- DPR別の最小構成(カードのサムネ等) -->
<picture>
<source
type="image/avif"
srcset="/thumb-400.avif 1x, /thumb-800.avif 2x"
/>
<img
src="/thumb-400.jpg"
srcset="/thumb-400.jpg 1x, /thumb-800.jpg 2x"
width="400" height="250"
alt="カードサムネ"
loading="lazy" decoding="async"
/>
</picture>
3.5 Next.js 15 と <picture>
の棲み分け
// TSX (Next.js)// Next.js 15:アートディレクションは <Image> だけでは表現しづらい
// 必要に応じて <picture> を使う(<Image>は意味のある単一トリムに最適)
/*
import Image from "next/image";
export function Hero() {
return (
<div className="hero">
<Image
src="/hero-wide-2000.avif"
alt="プロダクトを手にするユーザーの写真"
fill
sizes="(min-width: 1024px) 1000px, 92vw"
priority
/>
</div>
);
}
*/
4. 応用と使いどころ
- OGPサムネやバナーはテキストの位置が決まっているため、別トリム運用が有効(関連: OGP安全域)。
- 背景として使う場合は 背景のレスポンシブ設計 を。
- 色の破綻は sRGB正規化 で回避。
5. 公開前チェック
// Checklist# 公開前チェック(<picture> アートディレクション)
- 上から“的中する条件”の順に source を並べたか(PC条件→既定の順)
- 各トリムで srcset/sizes が“描画幅”に一致(過大DLなし)
- LCP候補なら preload を1枚だけ(imagesrcset/imagesizes を一致)
- CLSゼロ:width/height か aspect-ratio(ブレークポイント差はCSSで切替)
- 代替テキスト(alt)は“画像が伝える内容”を簡潔に(装飾は alt="")
- 画質/容量は /compare と /compressor で最終確認
6. まとめ
<picture> は“画角そのもの”を切り替えられるのが最大の強み。 順序・sizes
・予約サイズ・LCPの4点をテンプレ化すれば、破綻なく量産できます。 仕上げは /compare と /compressor で定量確認しましょう。
FAQ(よくある質問)
画像形式の基本方針は?(写真/スクショ/透過)
写真は AVIF / WebP(画質80–85%目安)、UIやスクショはPNG / WebP Lossless、単色ロゴはSVGが基本です。 実装の詳細は srcset/sizes設計ガイド と スクショ最適化 を参照してください。
圧縮しても画質を落とさないコツは?
実表示幅に合わせたリサイズ → 過大ダウンロードを防ぎ、
srcset/sizes
を 実描画幅に一致させます。画質は写真で 80–85% を起点に、ノイズやエッジを目視確認。 仕上げは /compare で Before/After を見比べるのがおすすめです。