CSSで画像を崩さず整える:max-widthとobject-fitの使い分け
画像の横幅が画面からはみ出すなら、まず使うのは max-width: 100% です。一方、商品カードやプロフィール一覧で画像の表示枠を同じ大きさにそろえるなら、枠の幅と高さを決めて object-fit: cover または contain を使います。
この2つは似た画像調整に見えますが、担当が違います。
max-width: 画像を親要素より大きくしないheight: auto: 元画像の縦横比を保って高さを調整するobject-fit: 決められた表示枠の中に画像をどう収めるか指定するobject-position: 切り抜く位置を調整する
ここがポイント: 記事内の画像には
max-width: 100%、同じサイズに並べるカード画像にはobject-fit: coverが基本です。
前提環境と最初に知っておきたいこと
CSSは画像ファイル自体を加工するのではなく、ブラウザ上の表示サイズと見せ方を変えます。 元画像の容量やピクセル数は、CSSを書いても小さくなりません。
この記事のコードは、通常のHTMLとCSSを扱える現在の主要ブラウザを想定しています。object-fit の値や動作は、CSS Images Module Level 3で定義されています。
例では次の画像を使います。
<img
class="sample-image"
src="images/product.jpg"
width="1200"
height="800"
alt="木製テーブルの上に置かれた商品"
>
HTMLの width と height には、原則として元画像の寸法を指定します。ブラウザが読み込み前に縦横比を計算して場所を確保できるため、画像が後から表示されたときのレイアウト移動を抑えられます。CSSで表示幅を変える場合でも、この属性を省く必要はありません。
alt には「画像」などの曖昧な語ではなく、画像が伝える内容を書きます。装飾だけの画像なら alt="" とします。
画像のはみ出しをmax-widthで防ぐ
文章中の画像を画面幅に収めたいだけなら、縦横比を保つ指定で十分です。
.content img {
max-width: 100%;
height: auto;
}
親要素が640px、画像本来の幅が1200pxなら、表示幅は最大640pxまで縮みます。親要素が1400pxになっても、画像は元の1200pxを超えて拡大されません。
width: 100%との違い
次の2つは同じではありません。
/* 親要素より大きい画像だけ縮める */
img {
max-width: 100%;
height: auto;
}
/* 小さい画像も親要素いっぱいまで拡大する */
img {
width: 100%;
height: auto;
}
width: 100% は、画像を常に親要素と同じ幅にします。300pxの画像を900pxまで引き伸ばせば、輪郭がぼやけることがあります。
本文画像では max-width: 100%、カードやバナーなど幅をそろえる部品では width: 100% と使い分けるのが実用的です。
max-widthだけでは高さはそろわない
縦長、横長、正方形の画像に max-width: 100% を指定しても、それぞれの縦横比は変わりません。商品カードを横に並べると、画像の下端がそろわない状態になります。
ここで必要になるのが object-fit です。
object-fitで画像枠を統一する
object-fit は、幅と高さが決まった画像ボックスの中で効果を発揮します。 値だけを指定しても、画像の表示枠が決まっていなければ変化が分かりにくい点に注意してください。
cover:枠全体を画像で埋める
商品カードや記事サムネイルでは、cover がよく合います。
<article class="product-card">
<img
class="product-card__image"
src="images/product.jpg"
width="1200"
height="800"
alt="木製テーブルの上に置かれた商品"
>
<h2>商品名</h2>
</article>
.product-card__image {
display: block;
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
aspect-ratio: 4 / 3 が表示枠の比率を決め、object-fit: cover がその枠を隙間なく埋めます。元画像の比率が枠と異なる場合、画像の上下または左右が切り取られます。
向いている用途は次のとおりです。
- 商品一覧のサムネイル
- ブログの記事カード
- スタッフ紹介の顔写真
- ギャラリーのタイル表示
画像の一部が隠れても、カード全体の整列を優先したい場面に適しています。
contain:画像全体を見せる
ロゴや商品写真を欠けさせたくない場合は contain を使います。
.logo-box {
width: 240px;
aspect-ratio: 3 / 2;
padding: 16px;
background: #f5f5f5;
}
.logo-box img {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
画像全体は表示されますが、枠と画像の縦横比が違えば余白が生まれます。余白が不具合なのではなく、画像を切らずに収めた結果です。
向いているのは、次のような画像です。
- 企業やサービスのロゴ
- 全体形状を見せたい商品写真
- 図表やスクリーンショット
- 端に重要な文字がある画像
coverとcontainの判断基準
迷ったら「切れてもよいか」で判断します。
- 枠を埋めることが優先:
cover - 画像全体の表示が優先:
contain - 元の比率のまま本文に置く:
max-width: 100%; height: auto;
object-fit の初期値は fill です。幅と高さを固定した画像に初期値のまま任せると、元画像と枠の比率によっては縦または横に伸びて見えます。比率を崩したくない固定枠では、cover か contain を明示します。
切り抜く位置をobject-positionで調整する
cover で重要な部分が切れる場合は、object-position で表示の基準位置を動かせます。
既定値は中央です。
.profile-image {
width: 160px;
height: 160px;
object-fit: cover;
object-position: center;
}
人物の顔が画像上部にあるなら、縦方向の位置を調整します。
.profile-image {
object-position: center 25%;
}
代表的な指定は次のとおりです。
object-position: center; /* 中央 */
object-position: top; /* 上を優先 */
object-position: left center; /* 左中央を優先 */
object-position: 70% 30%; /* 横70%、縦30%を基準にする */
ただし、画像ごとに被写体の位置が違う場合、全画像へ同じ値を指定しても解決しません。HTMLに画像別のクラスを付ける、CMSに焦点位置を保存する、切り抜き済み画像を用意する、といった運用が必要です。
実務で使える3つのパターン
用途別に、最小構成を確認します。
1. 記事本文の画像をレスポンシブにする
.article-body img {
display: block;
max-width: 100%;
height: auto;
}
display: block を加えると、インライン画像のベースラインによって下側にわずかな隙間が見える問題も避けやすくなります。
2. 商品カードを正方形でそろえる
.product-card img {
display: block;
width: 100%;
aspect-ratio: 1;
object-fit: cover;
border-radius: 8px;
}
aspect-ratio: 1 は 1 / 1 と同じで、正方形を意味します。カード幅が240pxなら画像枠は240×240px、スマートフォンで幅が変われば高さも同じ比率で変わります。
3. 最大サイズを決めて画像全体を表示する
.preview-image {
display: block;
max-width: 100%;
width: 600px;
height: 400px;
object-fit: contain;
background: #eee;
}
幅600pxを基本としつつ、狭い画面では max-width: 100% によって縮みます。ただし、固定した height: 400px は狭い画面でも残ります。枠自体も比率に応じて縮めたい場合は、次のようにします。
.preview-image {
display: block;
width: min(100%, 600px);
aspect-ratio: 3 / 2;
object-fit: contain;
background: #eee;
}
object-fitが効かないときの確認ポイント
最も多い原因は、画像ボックスの幅または高さが決まっていないことです。 次の順番で確認すると切り分けやすくなります。
幅と高さの両方が決まっているか
次の指定では、高さが元画像の比率で自動計算されるため、cover で切り抜くための枠がありません。
/* 変化が分かりにくい例 */
img {
width: 100%;
height: auto;
object-fit: cover;
}
固定高または aspect-ratio を指定します。
img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
object-fitを親要素に書いていないか
object-fit は、画像や動画などの置換要素に指定します。
/* NG */
.image-frame {
object-fit: cover;
}
/* 改善 */
.image-frame img {
width: 100%;
height: 100%;
object-fit: cover;
}
widthとheightだけで引き伸ばしていないか
/* 元画像と枠の比率が違うと変形する */
img {
width: 300px;
height: 200px;
}
/* 比率を保って枠を埋める */
img {
width: 300px;
height: 200px;
object-fit: cover;
}
CSSが別のルールに上書きされていないか
ブラウザの開発者ツールで対象の <img> を選び、width、height、aspect-ratio、object-fit の計算結果を確認します。打ち消し線が付いている宣言は、詳細度が高いセレクタや後から読み込まれたCSSに上書きされています。
!important をすぐ追加するのではなく、競合しているセレクタとCSSの読み込み順を先に直すほうが保守しやすくなります。
CSSだけでは解決しない問題
表示サイズを整えるCSSと、通信量を減らす画像配信は別の課題です。
幅400pxで表示する画像に4000pxのファイルを配信すると、CSS上はきれいに収まっても不要なデータを読み込む可能性があります。必要に応じて次も組み合わせます。
srcsetとsizesで表示条件に合う画像を選ばせる- WebPやAVIFなど、用途に合う形式を検討する
- 画面外の画像に
loading="lazy"を使う - HTMLの
widthとheightで読み込み前の領域を確保する - WordPressでは生成済みのサムネイルサイズを適切に選ぶ
また、cover は元画像を削除しているわけではありません。見えていない部分もダウンロードされるため、機密情報を隠す目的には使えません。公開してはいけない情報は、アップロード前に画像から完全に除去します。
background-imageとの使い分け
内容として必要な画像は <img>、純粋な装飾は background-image が基本です。
背景画像にも似た指定があります。
.hero {
min-height: 320px;
background-image: url("images/hero.jpg");
background-size: cover;
background-position: center;
}
使い分けは次のとおりです。
- 商品写真、人物写真、図表など本文の意味を担う:
<img>とobject-fit - 模様や雰囲気づくりなど、なくても内容が変わらない:
background-image - 画像の代替説明が必要:
<img>のaltを使う - 背景の上に文字を重ねる: コントラストを確認し、文字が読める背景色やオーバーレイも用意する
意味のある画像を背景にすると、alt に相当する代替テキストを直接持たせられません。見た目だけを理由に背景画像へ置き換えないことが重要です。
実装前のチェックリスト
最後に、画像が崩れないための確認点を用途別に整理します。
- 本文画像には
max-width: 100%とheight: autoを指定したか - 小さい画像まで拡大する必要があるかを考えて
widthとmax-widthを選んだか - 一覧画像では幅と高さ、または
aspect-ratioで枠を決めたか - 切れてよい画像に
cover、全体を見せる画像にcontainを使ったか coverで重要部分が隠れる場合にobject-positionを調整したか- HTMLに元画像の
width、height、適切なaltを設定したか - CSS上の縮小だけで済ませず、配信する画像容量も確認したか
まずは本文画像に max-width: 100%; height: auto; を適用し、サイズの異なる画像を並べる部品だけに aspect-ratio と object-fit を追加してください。次に確認すべきなのは、スマートフォン幅での切れ方と、cover によって商品名や人物の顔など重要な部分が隠れていないかです。
