【CSS】object-fitの使い方:画像トリミングと効かない時の対策

css-object-fit
ポートフォリオ向けサーバー
HTML/CSSスキルが活きる!
学んだ知識を活かして、
自分だけのブログを始めませんか?

WordPressブログなら、あなたのコーディング知識でデザインのカスタマイズが自由自在。
ブログデビューに最適な初心者向けサーバー環境を徹底比較しました。

CSSのobject-fitは、画像や動画の縦横比を保ったまま、指定した枠に合わせてトリミングやサイズ調整を行うプロパティです。

本記事では、各種値の使い分けやaspect-ratioとの組み合わせ、実務で直面しやすい「効かない」トラブルの解決策を解説します。

また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。

HTML/CSS学習者の方へ
「学んだコード、自分のブログで試してみませんか?」
多くのブロガーがデザインでつまずく中、コードが読めるあなたは圧倒的に有利です。
自由自在なサイト構築の第一歩となる、初心者向けサーバーを分かりやすく比較しました。

\ スキルを活かして情報発信 / ブログ向けレンタルサーバー4選を読む▶︎
目次

object-fitとは:画像や動画をトリミングする

Webサイトのデザインで、「画像が横に伸びて歪んでしまった」「サムネイルのサイズがバラバラで揃わない」と悩んだ経験はありませんか?

そんな時に活躍するのがobject-fitです。

object-fitを理解すれば、画像加工ソフトでの切り抜き作業なしで、CSSだけでトリミングやサイズ調整が可能になります。

ここでは、object-fitの使い方、object-fitの実装例、指定できるobject-fitの値の種類について解説します。

object-fitとは:画像や動画をトリミングする
  • 親要素の枠に合わせて中身を自動調整する仕組み
  • covercontainfillなどの値の違いと選び方

画像の要素であるimgタグの使い方を詳しく知りたい人は「【HTML】imgタグの使い方:src・altの使い分けや画像リサイズ・中央寄せ」を一読ください。

親要素の枠に合わせて中身を自動調整する仕組み

object-fitは、<img><video>といった要素そのものが、「自分自身に指定された幅と高さの枠組みの中で、どのように振る舞うか」を指定するプロパティです。

通常、画像に対して縦横のサイズを指定すると、元のアスペクト比が無視されて押し潰されたような見た目になります。

しかしobject-fitを併用することで、アスペクト比を保ったまま枠に収めたり、はみ出した部分を自動的にトリミングしたりすることが可能になります。

画像をコントロールするには、「object-fitを書く前に、画像(または動画)に対してwidthheight(枠のサイズ)を明確に指定すること」です。

⭕️ 画像サイズの強制による「歪み」を直す魔法のプロパティ

❌ 罠(object-fitなし)
比率が無視され、横に潰れてしまう

黒い犬の画像

⭕️ 成功(object-fit: cover)
比率を保ったまま、枠に合わせて切り抜かれる

黒い犬の画像
/* ❌ 縦横のサイズだけを強制指定してしまう */
.img-fail {
  width: 150px;
  height: 150px; /* 🚨 元が長方形の画像だと、正方形に押し潰されて不格好になる! */
}

/* ⭕️ 枠のサイズを決めたら、必ず object-fit をセットにする */
.img-success {
  width: 150px;
  height: 150px;
  object-fit: cover; /* 💡 歪ませず、はみ出た部分を自動で切り抜く! */
}
HTMLコード表示
<div class="of-basic-wrapper">
  
  <p class="of-basic-caption">⭕️ 画像サイズの強制による「歪み」を直す魔法のプロパティ</p>

  <div class="of-basic-demo-area">
    
    <div class="of-basic-item">
      <p class="of-basic-label" style="color:#dc3545;">❌ 罠(object-fitなし)<br><small>比率が無視され、横に潰れてしまう</small></p>
      <img src="https://picsum.photos/id/237/600/400" alt="黒い犬の画像" class="of-basic-img is-bad-squish">
    </div>

    <div class="of-basic-item">
      <p class="of-basic-label" style="color:#0d6efd;">⭕️ 成功(object-fit: cover)<br><small>比率を保ったまま、枠に合わせて切り抜かれる</small></p>
      <img src="https://picsum.photos/id/237/600/400" alt="黒い犬の画像" class="of-basic-img is-good-fit">
    </div>

  </div>

  <div class="of-basic-code-area">
    <span class="hl-comment">/* ❌ 縦横のサイズだけを強制指定してしまう */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">150px;</span> <span class="hl-comment">/* 🚨 元が長方形の画像だと、正方形に押し潰されて不格好になる! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 枠のサイズを決めたら、必ず object-fit をセットにする */</span><br>
    <span class="hl-blue">.img-success</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 歪ませず、はみ出た部分を自動で切り抜く! */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-basic-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-basic-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-basic-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.of-basic-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 200px;
}

.of-basic-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* 💡 画像の共通設定(枠のサイズを正方形に強制) */
.of-basic-img {
  width: 150px;
  height: 150px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  background-color: #ddd; /* 読み込み前のプレースホルダー */
}

/* =❌ 罠:サイズ指定のみ(押し潰される)= */
.is-bad-squish {
  /* object-fitがないため、長方形の画像が150x150に歪んで表示される */
}

/* =⭕️ 正解:object-fit: cover を追加= */
.is-good-fit {
  object-fit: cover; /* 💡 これだけでプロの仕上がりに! */
}

/* =コード解説エリア= */
.of-basic-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

幅や高さの設定について詳しく知りたい人は「【CSS】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。

cover・contain・fillなどの値の違いと選び方

object-fitには、用途に合わせて使い分けるいくつかの重要な値(オプション)が存在します。

  • cover
    画像の比率を保ったまま、指定した枠を覆い尽くすように拡大・縮小します。
    枠からはみ出た部分は見えなくなります。
    カード型のサムネイルやヒーローヘッダー(メインビジュアル)で使われます。
  • contain
    画像の比率を保ったまま、指定した枠の中に収まるように調整します。
    画像が見切れることはありませんが、枠と画像の比率が違う場合、上下や左右に余白ができます。
  • fill
    初期値です。
    画像の比率を無視して、指定した枠のサイズに合わせます(画像が歪みます)。
  • scale down
    画像の本来のサイズとcontainを比較し、「より小さくなる方」を採用します。
    小さなアイコンが枠に合わせて巨大化してぼやけるのを防ぐのに役立ちます。

プロパティを選ぶ際は、「『写真の雰囲気』を伝えるサムネイルや背景にはcoverを使い、『情報そのもの(ロゴ、QRコード、文字入りバナー)』を伝える画像にはcontainを使うこと」です。

画像の持つ役割によって値を的確に使い分けましょう。

⭕️ 画像の「役割」に合わせて値を使い分けろ!

cover
(枠を埋める / はみ出しカット)

風景画像

contain
(見切れない / 余白ができる)

風景画像

fill (初期値)
(比率無視 / 歪む)

風景画像

scale-down
(元のサイズより大きくならない)

小さな風景画像
/* ⭕️ サムネイルや背景写真には cover(余白を作らない) */
.thumb-img {
  object-fit: cover;
}

/* ⭕️ 企業ロゴや読ませるバナー画像には contain(絶対に見切れさせない) */
.logo-img {
  object-fit: contain;
}
HTMLコード表示
<div class="of-options-wrapper">
  
  <p class="of-options-caption">⭕️ 画像の「役割」に合わせて値を使い分けろ!</p>

  <div class="of-options-demo-area">
    
    <div class="of-options-item">
      <p class="of-options-label">cover<br><small>(枠を埋める / はみ出しカット)</small></p>
      <div class="img-container">
        <img src="https://picsum.photos/id/1015/600/300" alt="風景画像" class="of-options-img is-cover">
      </div>
    </div>

    <div class="of-options-item">
      <p class="of-options-label">contain<br><small>(見切れない / 余白ができる)</small></p>
      <div class="img-container">
        <img src="https://picsum.photos/id/1015/600/300" alt="風景画像" class="of-options-img is-contain">
      </div>
    </div>

    <div class="of-options-item">
      <p class="of-options-label">fill (初期値)<br><small>(比率無視 / 歪む)</small></p>
      <div class="img-container">
        <img src="https://picsum.photos/id/1015/600/300" alt="風景画像" class="of-options-img is-fill">
      </div>
    </div>

    <div class="of-options-item">
      <p class="of-options-label">scale-down<br><small>(元のサイズより大きくならない)</small></p>
      <div class="img-container">
        <img src="https://picsum.photos/id/1015/100/50" alt="小さな風景画像" class="of-options-img is-scale-down">
      </div>
    </div>

  </div>

  <div class="of-options-code-area">
    <span class="hl-comment">/* ⭕️ サムネイルや背景写真には cover(余白を作らない) */</span><br>
    <span class="hl-blue">.thumb-img</span> {<br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 企業ロゴや読ませるバナー画像には contain(絶対に見切れさせない) */</span><br>
    <span class="hl-blue">.logo-img</span> {<br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">contain;</span><br>
    }
  </div>

</div>
CSSコード表示
.of-options-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-options-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-options-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.of-options-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 140px;
}

.of-options-label {
  font-size: 12px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 40px;
}

/* 💡 余白(レターボックス)が分かるように親要素に色をつける */
.img-container {
  width: 140px;
  height: 140px;
  background-color: #dee2e6; /* 余白部分の色 */
  border: 1px solid #ced4da;
  border-radius: 4px;
  overflow: hidden;
}

/* 💡 画像の共通設定(親要素にぴったり合わせる) */
.of-options-img {
  width: 100%;
  height: 100%;
  display: block;
}

/* =各種オプションの指定= */
.is-cover {
  object-fit: cover; /* 枠を埋めるよう拡大され、左右が切れる */
}

.is-contain {
  object-fit: contain; /* 全体を表示するため、上下にグレーの余白ができる */
}

.is-fill {
  object-fit: fill; /* 比率を無視して正方形に無理やり引き伸ばされる */
}

.is-scale-down {
  object-fit: scale-down; /* 画像が小さい場合、枠に合わせて拡大されず中央に配置される */
}

/* =コード解説エリア= */
.of-options-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

aspect-ratioや動画(video)への適用

object-fitの真価は、固定サイズの箱に画像を収めることだけではありません。

現代のWebデザインに欠かせないレスポンシブ対応(画面サイズに応じた伸縮)やリッチな動画コンテンツの配置と組み合わせることで、強力なレイアウト手法へと昇華します。

ここでは、aspect-ratioとの組み合わせや動画要素への適用方法、「背景画像との違い」について解説します。

aspect-ratioや動画(video)への適用
  • aspect-ratioと併用してレスポンシブな正方形や16:9を作る
  • HTMLの動画(video要素)を枠いっぱいに表示する
  • 背景画像(background-image)には使えない?

aspect-ratioと併用してレスポンシブな正方形や16:9を作る

画像やサムネイルの縦横比を固定するために活躍しているプロパティがaspect-ratioです。

aspect-ratioobject-fitを併用することで、画面幅に合わせて伸縮しつつ、歪まない「16:9」や「1:1(正方形)」のサムネイルを作ることができます。

レスポンシブな画像配置は、「width: 100%;aspect-ratio: 比率;object-fit: cover;の3点セットを崩さないこと」です。

かつて「padding-topのパーセント指定」を使って複雑に実装していたアスペクト比の固定は、現在は3行だけで実装できます。

⭕️ レスポンシブなサムネイルは「比率+cover」の3点セットで作れ!

❌ 罠(比率指定のみ)
枠は16:9になるが、画像が歪む

犬の画像

⭕️ 成功(16:9 + cover)
歪まずに美しくトリミングされる

犬の画像

⭕️ 成功(1:1 + cover)
どんな元画像でも綺麗な正方形に

犬の画像
/* ❌ 枠の比率だけ変えて、中身のトリミングを忘れる */
.thumb-fail {
  width: 100%;
  aspect-ratio: 16 / 9; /* 🚨 枠は16:9になるが画像が歪む! */
}

/* ⭕️ 幅100% + 比率 + cover の最強3点セット */
.thumb-success {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover; /* 💡 これで完璧にトリミングされる! */
}
HTMLコード表示
<div class="of-ratio-wrapper">
  
  <p class="of-ratio-caption">⭕️ レスポンシブなサムネイルは「比率+cover」の3点セットで作れ!</p>

  <div class="of-ratio-demo-area">
    
    <div class="of-ratio-item">
      <p class="of-ratio-label" style="color:#dc3545;">❌ 罠(比率指定のみ)<br><small>枠は16:9になるが、画像が歪む</small></p>
      <div class="ratio-container">
        <img src="https://picsum.photos/id/1025/400/400" alt="犬の画像" class="ratio-img is-bad-ratio">
      </div>
    </div>

    <div class="of-ratio-item">
      <p class="of-ratio-label" style="color:#0d6efd;">⭕️ 成功(16:9 + cover)<br><small>歪まずに美しくトリミングされる</small></p>
      <div class="ratio-container">
        <img src="https://picsum.photos/id/1025/400/400" alt="犬の画像" class="ratio-img is-good-16-9">
      </div>
    </div>

    <div class="of-ratio-item">
      <p class="of-ratio-label" style="color:#0d6efd;">⭕️ 成功(1:1 + cover)<br><small>どんな元画像でも綺麗な正方形に</small></p>
      <div class="ratio-container" style="width: 120px;">
        <img src="https://picsum.photos/id/1025/600/300" alt="犬の画像" class="ratio-img is-good-1-1">
      </div>
    </div>

  </div>

  <div class="of-ratio-code-area">
    <span class="hl-comment">/* ❌ 枠の比率だけ変えて、中身のトリミングを忘れる */</span><br>
    <span class="hl-blue">.thumb-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">aspect-ratio:</span> <span class="hl-red">16 / 9;</span> <span class="hl-comment">/* 🚨 枠は16:9になるが画像が歪む! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 幅100% + 比率 + cover の最強3点セット */</span><br>
    <span class="hl-blue">.thumb-success</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">aspect-ratio:</span> <span class="hl-red">16 / 9;</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 これで完璧にトリミングされる! */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-ratio-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-ratio-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-ratio-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
  align-items: flex-end;
}

.of-ratio-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.of-ratio-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 40px;
}

/* デモ用のコンテナ(親要素) */
.ratio-container {
  width: 180px; /* PCでもスマホでも見やすいサイズ */
  background-color: #ddd;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

/* =❌ 罠:比率指定のみ(歪む)= */
.is-bad-ratio {
  width: 100%;
  aspect-ratio: 16 / 9;
  /* object-fitがないため、元が正方形の画像が横に引き伸ばされる */
}

/* =⭕️ 正解:16:9 + cover= */
.is-good-16-9 {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover; /* 💡 完璧なサムネイル */
}

/* =⭕️ 正解:1:1 + cover= */
.is-good-1-1 {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover; /* 💡 完璧な正方形アイコン */
}

/* =コード解説エリア= */
.of-ratio-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

比率を調整するaspect-ratioの使い方を詳しく知りたい人は「【CSS】aspect-ratioの使い方:画像や動画の縦横比を固定・維持」を一読ください。

HTMLの動画(video要素)を枠いっぱいに表示する

Webサイトのファーストビュー(ヒーローヘッダー)で、全画面にダイナミックな動画をループ再生させるデザインは人気があります。

この時、<video> 要素を枠いっぱいに表示するためにもobject-fitが活躍します。

object-fit<img>要素だけでなく、<video>要素に対しても同じように機能します。

背景動画を綺麗に配置するには、「動画要素(<video>)は画像(<img>)と同じ扱いだと認識し、背景として全画面に敷き詰める時はobject-fit: cover;を指定すること」です。

⭕️ 動画の余白(黒帯)も、cover一発で消し飛ばせる!

❌ 罠(サイズ指定のみ)
比率を保とうとして上下に黒帯が出る

HERO

⭕️ 成功(coverを指定)
黒帯が消え、枠いっぱいに広がる!

HERO
/* ❌ 動画を幅100%・高さ100%にするだけで満足してしまう */
video.bg-fail {
  width: 100%;
  height: 100%; /* 🚨 これだけだと上下に黒い余白(レターボックス)が出る! */
}

/* ⭕️ 背景動画なら、画像と同じように cover を指定する */
video.bg-success {
  width: 100%;
  height: 100%;
  object-fit: cover; /* 💡 邪魔な余白が消え、全画面に美しく広がる */
}
HTMLコード表示
<div class="of-video-wrapper">
  
  <p class="of-video-caption">⭕️ 動画の余白(黒帯)も、cover一発で消し飛ばせる!</p>

  <div class="of-video-demo-area">
    
    <div class="of-video-item">
      <p class="of-video-label" style="color:#dc3545;">❌ 罠(サイズ指定のみ)<br><small>比率を保とうとして上下に黒帯が出る</small></p>
      <div class="video-hero-box">
        <video class="video-elem is-bad-video" autoplay muted loop playsinline>
          <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
        </video>
        <span class="video-overlay-text">HERO</span>
      </div>
    </div>

    <div class="of-video-item">
      <p class="of-video-label" style="color:#0d6efd;">⭕️ 成功(coverを指定)<br><small>黒帯が消え、枠いっぱいに広がる!</small></p>
      <div class="video-hero-box">
        <video class="video-elem is-good-video" autoplay muted loop playsinline>
          <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
        </video>
        <span class="video-overlay-text">HERO</span>
      </div>
    </div>

  </div>

  <div class="of-video-code-area">
    <span class="hl-comment">/* ❌ 動画を幅100%・高さ100%にするだけで満足してしまう */</span><br>
    <span class="hl-blue">video.bg-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">100%;</span> <span class="hl-comment">/* 🚨 これだけだと上下に黒い余白(レターボックス)が出る! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 背景動画なら、画像と同じように cover を指定する */</span><br>
    <span class="hl-blue">video.bg-success</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 邪魔な余白が消え、全画面に美しく広がる */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-video-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-video-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-video-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.of-video-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.of-video-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 40px;
}

/* 💡 ヒーローバナーを模したコンテナ */
.video-hero-box {
  position: relative;
  width: 200px;
  height: 250px; /* 縦長の枠をわざと用意する */
  background-color: #000; /* 黒帯が分かりやすいように背景を黒に */
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 10px rgba(0,0,0,0.2);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ヒーロー上のテキスト */
.video-overlay-text {
  position: relative;
  z-index: 2;
  color: #fff;
  font-size: 24px;
  font-weight: bold;
  text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}

/* 💡 動画要素の共通設定 */
.video-elem {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

/* =❌ 罠:サイズ指定のみ(縦長枠に16:9動画を入れると上下が黒くなる)= */
.is-bad-video {
  /* object-fitがないため、デフォルトのcontainのような挙動になる */
}

/* =⭕️ 正解:coverを指定(枠を埋め尽くす)= */
.is-good-video {
  object-fit: cover; /* 💡 余白が消え、枠いっぱいに広がる */
}

/* =コード解説エリア= */
.of-video-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

動画要素であるvideoタグの使い方を詳しく知りたい人は「【HTML】videoタグの使い方:自動再生・レスポンシブ・背景動画」を一読ください。

背景画像(background-image)には使えない?

画像のトリミング方法は以下の通りです。

  • HTMLに書いた画像(<img>) → object-fit を使う。
  • CSSに書いた画像(background-image) → background-size を使う。

「HTMLの画像か、CSSの背景か」によって、使うべきプロパティの名前が変わるということを覚えておきましょう。

⭕️ 背景画像(CSS)には「background-size: cover;」を使え!

❌ 罠(object-fitを使用)
背景画像には無効!画像がリピートしてしまう

divタグ

⭕️ 正解(background-sizeを使用)
背景画像は background-size でコントロールする

divタグ
/* ❌ 背景画像に対して object-fit を書いてしまう */
.bg-fail {
  background-image: url(‘image.jpg’);
  object-fit: cover; /* 🚨 背景には効かない!無視される */
}

/* ⭕️ CSSの背景画像なら「background-size」一択! */
.bg-success {
  background-image: url(‘image.jpg’);
  background-size: cover; /* 💡 背景画像を枠いっぱいに広げる正しいプロパティ */
  background-position: center; /* 💡 ついでに中央寄せにすると綺麗! */
}
HTMLコード表示
<div class="of-bg-wrapper">
  
  <p class="of-bg-caption">⭕️ 背景画像(CSS)には「background-size: cover;」を使え!</p>

  <div class="of-bg-demo-area">
    
    <div class="of-bg-item">
      <p class="of-bg-label" style="color:#dc3545;">❌ 罠(object-fitを使用)<br><small>背景画像には無効!画像がリピートしてしまう</small></p>
      <div class="bg-box is-bad-bg-fit">
        <span>divタグ</span>
      </div>
    </div>

    <div class="of-bg-item">
      <p class="of-bg-label" style="color:#0d6efd;">⭕️ 正解(background-sizeを使用)<br><small>背景画像は background-size でコントロールする</small></p>
      
      <div class="bg-box is-good-bg-size">
        <span>divタグ</span>
      </div>
    </div>

  </div>

  <div class="of-bg-code-area">
    <span class="hl-comment">/* ❌ 背景画像に対して object-fit を書いてしまう */</span><br>
    <span class="hl-blue">.bg-fail</span> {<br>
      <span class="hl-green">background-image:</span> <span class="hl-red">url('image.jpg');</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 🚨 背景には効かない!無視される */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ CSSの背景画像なら「background-size」一択! */</span><br>
    <span class="hl-blue">.bg-success</span> {<br>
      <span class="hl-green">background-image:</span> <span class="hl-red">url('image.jpg');</span><br>
      <span class="hl-green">background-size:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 背景画像を枠いっぱいに広げる正しいプロパティ */</span><br>
      <span class="hl-green">background-position:</span> <span class="hl-red">center;</span> <span class="hl-comment">/* 💡 ついでに中央寄せにすると綺麗! */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-bg-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-bg-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-bg-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.of-bg-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.of-bg-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 40px;
}

/* 💡 divタグの共通設定 */
.bg-box {
  width: 200px;
  height: 150px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  /* デモ用にわざと小さな画像を背景に指定 */
  background-image: url('https://picsum.photos/id/1018/50/50');
}

/* divの中のテキスト装飾 */
.bg-box span {
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  padding: 5px 10px;
  border-radius: 4px;
  font-weight: bold;
  font-size: 14px;
}

/* =❌ 罠:背景画像にobject-fit(無効になり画像がタイル状にリピートする)= */
.is-bad-bg-fit {
  object-fit: cover; /* まったく効かない */
}

/* =⭕️ 正解:背景画像にはbackground-size: cover= */
.is-good-bg-size {
  background-size: cover; /* 💡 背景画像が枠いっぱいに広がる */
  background-position: center; /* 中央を基準にする */
  background-repeat: no-repeat; /* 念のためのリピート防止 */
}

/* =コード解説エリア= */
.of-bg-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

トリミング位置を調整するobject-positionの使い方

object-fit: cover;は画像を枠いっぱいに敷き詰める便利なプロパティですが、時に「人物の顔が見切れてしまった」「見せたい商品が端に寄ってしまった」という問題が発生します。

そんな時にセットで覚えるべきなのが、切り抜く位置をコントロールするobject-positionです。

このプロパティを使いこなせば、位置を上下左右やパーセンテージで自在に指定し、切り抜くことができるようになります。

トリミング位置を調整するobject-positionの使い方
  • object-positionで中央や上を指定する
  • ホバー時に画像をズームさせるおしゃれなエフェクト

object-positionで中央や上を指定する

object-fitを指定した際、デフォルトのトリミング位置は中央となっており、画像の「ど真ん中(50% 50%)」を中心に切り抜かれます。

しかし、人物の写真などは顔が上部に配置されていることが多く、そのままでは首から下しか表示されないといったことも多々あります。

これを防ぐために、object-position: top;object-position: bottom;、あるいはobject-position: 50% 20%;といった数値指定で焦点をズラすテクニックが必須となります。

トリミングを実装する際は、「人物の写真は無条件でobject-position: top;(またはそれに近いパーセンテージ)を指定し、顔が見切れるリスクを最初から潰しておくこと」です。

⭕️ 縦長の画像を横長枠に入れる時、焦点(position)を指定して顔を残す!

❌ 罠(デフォルト/center)
真ん中が抜け、鼻や口元になる

女性の顔

⭕️ 成功(topを指定)
上部を基準にし、目元(顔)を残す

女性の顔

💡 参考(bottomを指定)
下部を基準にし、首元になる

女性の顔
/* ❌ 何も指定せず、人物の顔を切ってしまう */
.img-fail {
  width: 100%;
  height: 100px; /* 💡 縦長のバナー枠 */
  object-fit: cover; /* 🚨 デフォルトの center が適用され、胴体や口元が抜かれる */
}

/* ⭕️ 人物画像は top や 20% などを指定して顔を守る! */
.img-success {
  width: 100%;
  height: 100px;
  object-fit: cover;
  object-position: top; /* 💡 画像の「上端」を基準にして、見せたい顔をトリミングする */
}
HTMLコード表示
<div class="obj-pos-wrapper">
  
  <p class="obj-pos-caption">⭕️ 縦長の画像を横長枠に入れる時、焦点(position)を指定して顔を残す!</p>

  <div class="obj-pos-demo-area">
    
    <div class="obj-pos-item">
      <p class="obj-pos-label trap-label">❌ 罠(デフォルト/center)<br><span class="label-small">真ん中が抜け、鼻や口元になる</span></p>
      <img src="https://picsum.photos/id/1027/400/800" alt="女性の顔" class="pos-img is-center">
    </div>

    <div class="obj-pos-item">
      <p class="obj-pos-label success-label">⭕️ 成功(topを指定)<br><span class="label-small">上部を基準にし、目元(顔)を残す</span></p>
      <img src="https://picsum.photos/id/1027/400/800" alt="女性の顔" class="pos-img is-top">
    </div>

    <div class="obj-pos-item">
      <p class="obj-pos-label">💡 参考(bottomを指定)<br><span class="label-small">下部を基準にし、首元になる</span></p>
      <img src="https://picsum.photos/id/1027/400/800" alt="女性の顔" class="pos-img is-bottom">
    </div>

  </div>

  <div class="obj-pos-code-area">
    <span class="hl-comment">/* ❌ 何も指定せず、人物の顔を切ってしまう */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">100px;</span> <span class="hl-comment">/* 💡 縦長のバナー枠 */</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 🚨 デフォルトの center が適用され、胴体や口元が抜かれる */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 人物画像は top や 20% などを指定して顔を守る! */</span><br>
    <span class="hl-blue">.img-success</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">100px;</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span><br>
      <span class="hl-green">object-position:</span> <span class="hl-red">top;</span> <span class="hl-comment">/* 💡 画像の「上端」を基準にして、見せたい顔をトリミングする */</span><br>
    }
  </div>

</div>
CSSコード表示
.obj-pos-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.obj-pos-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.obj-pos-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.obj-pos-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 180px;
}

.obj-pos-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.4;
  height: 40px;
}

.trap-label { color: #dc3545; }
.success-label { color: #0d6efd; }
.label-small { font-size: 11px; font-weight: normal; color: #555; }

/* 💡 画像の共通設定(高さを狭くして横長バナー風にする) */
.pos-img {
  width: 100%;
  height: 280px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  object-fit: cover; /* 全てcoverを適用しておく */
  display: block;
}

/* =❌ 罠:デフォルト(中央)= */
.is-center {
  object-position: center; /* 💡 画像の真ん中(鼻・口)が抜かれる */
}

/* =⭕️ 正解:上(top)を指定= */
.is-top {
  object-position: top; /* 💡 画像の上端(目・頭)が抜かれる */
}

/* =💡 参考:下(bottom)を指定= */
.is-bottom {
  object-position: bottom; /* 💡 画像の下端(首・肩)が抜かれる */
}

/* =コード解説エリア= */
.obj-pos-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

ホバー時に画像をズームさせるおしゃれなエフェクト

Webサイトのカード型レイアウトで、マウスを乗せた時に画像がフワッと拡大するズームエフェクトは、ユーザーのクリック率を高める人気でおしゃれなマイクロインタラクションです。

このエフェクトは、object-fit: cover;transform: scale()を組み合わせることで、画像が歪むことなく実装できます。

ホバーズームを実装する際は以下の3点セットです。

  1. 親要素(画像を入れる箱)にoverflow: hidden;を指定し、はみ出た部分を隠す。
  2. 拡大にはレイアウトに影響を与えないtransform: scale(1.1);を使う。
  3. 滑らかに動かすためのtransitionは、:hover 側ではなく「通常時」の<img>に書く。

⭕️ ホバーズームは「親要素のoverflow: hidden」と「scale」で作れ!

❌ 罠(widthを変更)
枠からはみ出し、隣の要素を押しのける

風景

⭕️ 成功(scale + hidden)
枠内で美しくフワッとズームする

風景
/* ❌ 枠からはみ出す対策をせず、width を変えてしまう */
.card-fail img:hover {
  width: 110%; /* 🚨 ガタガタとレイアウトが崩れる原因! */
}

/* ⭕️ 親で隠し、子を scale で滑らかに拡大する! */
.card-success {
  overflow: hidden; /* 💡 1. 枠からはみ出た部分を隠す(超重要) */
}
.card-success img {
  object-fit: cover;
  transition: transform 0.4s ease; /* 💡 2. 通常時に transition を書く */
}
.card-success img:hover {
  transform: scale(1.1); /* 💡 3. width ではなく scale で拡大! */
}
HTMLコード表示
<div class="obj-zoom-wrapper">
  
  <p class="obj-zoom-caption">⭕️ ホバーズームは「親要素のoverflow: hidden」と「scale」で作れ!</p>

  <div class="obj-zoom-demo-area">
    
    <div class="obj-zoom-item">
      <p class="obj-zoom-label trap-label">❌ 罠(widthを変更)<br><span class="label-small">枠からはみ出し、隣の要素を押しのける</span></p>
      
      <div class="zoom-card is-trap-card">
        <img src="https://picsum.photos/id/1015/400/300" alt="風景" class="zoom-img is-trap-img">
      </div>
    </div>

    <div class="obj-zoom-item">
      <p class="obj-zoom-label success-label">⭕️ 成功(scale + hidden)<br><span class="label-small">枠内で美しくフワッとズームする</span></p>
      
      <div class="zoom-card is-success-card">
        <img src="https://picsum.photos/id/1015/400/300" alt="風景" class="zoom-img is-success-img">
      </div>
    </div>

  </div>

  <div class="obj-zoom-code-area">
    <span class="hl-comment">/* ❌ 枠からはみ出す対策をせず、width を変えてしまう */</span><br>
    <span class="hl-blue">.card-fail img:hover</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">110%;</span> <span class="hl-comment">/* 🚨 ガタガタとレイアウトが崩れる原因! */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 親で隠し、子を scale で滑らかに拡大する! */</span><br>
    <span class="hl-blue">.card-success</span> {<br>
      <span class="hl-green">overflow:</span> <span class="hl-red">hidden;</span> <span class="hl-comment">/* 💡 1. 枠からはみ出た部分を隠す(超重要) */</span><br>
    }<br>
    <span class="hl-blue">.card-success img</span> {<br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span><br>
      <span class="hl-green">transition:</span> <span class="hl-red">transform 0.4s ease;</span> <span class="hl-comment">/* 💡 2. 通常時に transition を書く */</span><br>
    }<br>
    <span class="hl-blue">.card-success img:hover</span> {<br>
      <span class="hl-green">transform:</span> <span class="hl-red">scale(1.1);</span> <span class="hl-comment">/* 💡 3. width ではなく scale で拡大! */</span><br>
    }
  </div>

</div>
CSSコード表示
.obj-zoom-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.obj-zoom-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.obj-zoom-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 40px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.obj-zoom-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 220px;
}

.obj-zoom-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  line-height: 1.4;
  height: 40px;
}

/* カードの共通設定 */
.zoom-card {
  width: 200px;
  height: 150px;
  border-radius: 8px;
  background-color: #dee2e6; /* 枠が分かるように色をつけておく */
  box-shadow: 0 4px 10px rgba(0,0,0,0.1);
  /* 罠と成功の違いを出すため、ここでは overflow: hidden はまだ書かない */
}

/* 画像の共通設定 */
.zoom-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* =❌ 罠:親に overflow: hidden がなく、widthを広げている= */
.is-trap-card {
  /* overflow: hidden; なし */
}
.is-trap-img {
  transition: width 0.4s ease, height 0.4s ease;
}
.is-trap-card:hover .is-trap-img {
  /* 🚨 画像自体が大きくなり、枠からはみ出して崩れる */
  width: 115%;
  height: 115%;
}

/* =⭕️ 正解:overflow:hidden と scale を使う= */
.is-success-card {
  overflow: hidden; /* 💡 枠からはみ出た部分を隠す(必須!) */
}
.is-success-img {
  transition: transform 0.4s ease; /* 💡 滑らかな動きの指定 */
}
.is-success-card:hover .is-success-img {
  transform: scale(1.15); /* 💡 レイアウトを崩さずに1.15倍に拡大 */
}

/* =コード解説エリア= */
.obj-zoom-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

はみ出しを防ぐoverflow、ズームエフェクトを実現するtransform、動きをつけるtransitionの使い方を詳しく知りたい人は以下から一読ください。

object-fitが効かない!原因と解決策

「CSSの構文は間違っていないはずなのに、なぜかobject-fitが効かない!」と頭を抱えるのは、Webデザインを学ぶすべての人が一度は通る道です。

ここでは、実務の現場でも頻発する「object-fitが無視されてしまう2大原因」と解決策を解説します。

object-fitが効かない!原因と解決策
  • widthheightを両方指定していない
  • インライン要素に入れている場合の対策

widthとheightを両方指定していない

object-fitが効かない原因の第1位が、「対象の画像(または動画)に対して、明確な『枠(サイズ)』が指定されていない」という状態です。

object-fitは、「指定された枠組みの中で、中身をどのようにトリミング・調整するか」を決めるプロパティです。

そのため、画像に対してwidthheightのどちらか一方しか指定されていなかったり、両方ともautoになっていたりすると、画像は「元の縦横比を保ったまま拡大・縮小」されるだけで、トリミングすべき枠が存在しないためobject-fitは無効化されます。

効かない時は、「object-fitを使う時は、画像要素にwidthheight(またはaspect-ratio)を『両方セットで』指定して、目に見えない枠を定義すること」です。

⭕️ トリミングするための「絶対的な枠(幅と高さ)」を作れ!

❌ 罠(heightの指定忘れ)
トリミングされず、縦に間延びする

縦長の画像

⭕️ 成功(幅と高さを両方指定)
枠が固定され、美しくトリミングされる

縦長の画像
/* ❌ 幅だけ指定して、高さを忘れる(またはautoのまま) */
.img-fail {
  width: 100%; /* 🚨 高さの指定がないと、coverは発動しない! */
  object-fit: cover;
}

/* ⭕️ widthとheight(またはaspect-ratio)を必ず両方書く! */
.img-success {
  width: 100%;
  height: 150px; /* 💡 高さが固定されることで、初めて「はみ出る部分」が生まれる */
  object-fit: cover; /* 💡 ここで完璧にトリミングされる */
}
HTMLコード表示
<div class="of-error-size-wrapper">
  
  <p class="of-error-size-caption">⭕️ トリミングするための「絶対的な枠(幅と高さ)」を作れ!</p>

  <div class="of-error-size-demo-area">
    
    <div class="of-error-size-item">
      <p class="of-error-size-label" style="color:#dc3545;">❌ 罠(heightの指定忘れ)<br><small>トリミングされず、縦に間延びする</small></p>
      
      <div class="of-error-size-box">
        <img src="https://picsum.photos/id/1011/400/600" alt="縦長の画像" class="size-img is-bad-height">
      </div>
    </div>

    <div class="of-error-size-item">
      <p class="of-error-size-label" style="color:#0d6efd;">⭕️ 成功(幅と高さを両方指定)<br><small>枠が固定され、美しくトリミングされる</small></p>
      
      <div class="of-error-size-box">
        <img src="https://picsum.photos/id/1011/400/600" alt="縦長の画像" class="size-img is-good-height">
      </div>
    </div>

  </div>

  <div class="of-error-size-code-area">
    <span class="hl-comment">/* ❌ 幅だけ指定して、高さを忘れる(またはautoのまま) */</span><br>
    <span class="hl-blue">.img-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span> <span class="hl-comment">/* 🚨 高さの指定がないと、coverは発動しない! */</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ widthとheight(またはaspect-ratio)を必ず両方書く! */</span><br>
    <span class="hl-blue">.img-success</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">150px;</span> <span class="hl-comment">/* 💡 高さが固定されることで、初めて「はみ出る部分」が生まれる */</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 ここで完璧にトリミングされる */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-error-size-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-error-size-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-error-size-demo-area {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
  align-items: flex-start;
}

.of-error-size-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 200px;
}

.of-error-size-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  line-height: 1.5;
}

/* デモ用のコンテナ(親要素) */
.of-error-size-box {
  width: 100%;
  background-color: #ddd;
  border: 2px dashed #999; /* 意図した「枠」が見えるようにする */
  border-radius: 8px;
  overflow: hidden;
}

/* =❌ 罠:高さ指定なし(元の比率で長くなってしまう)= */
.size-img.is-bad-height {
  width: 100%;
  /* heightの指定なし(自動で伸びる) */
  object-fit: cover; /* 効かない */
  display: block;
}

/* =⭕️ 正解:高さ指定あり(指定した枠に合わせてトリミング)= */
.size-img.is-good-height {
  width: 100%;
  height: 150px; /* 💡 高さを明確に定義 */
  object-fit: cover; /* 💡 これで効く */
  display: block;
}

/* =コード解説エリア= */
.of-error-size-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

改めて、様々な要素に対する幅や高さの設定方法や縦横比を調整するaspect-ratioの使い方を詳しく知りたい人は以下から一読ください。

インライン要素に入れている場合の対策

画像(<img>)を単体で置くのではなく、リンクを機能させる<a>タグで囲んだり、装飾のために<span>タグで囲んだりすることは多々あります。

しかし、この「囲んだ親要素」がインライン要素である場合、注意する点があります。

「リンク付きの正方形サムネイルを作ろう!」と考え、親である<a><span>タグに対してwidth: 200px; height: 200px;を指定し、中の<img>width: 100%; height: 100%; object-fit: cover;を設定したとします。

結果、画像は正方形にならずレイアウトが崩壊します。

なぜなら、<a><span>といったインライン要素には、CSSの仕様上widthheightが一切効かないからです。

親の枠組み自体が存在しないため、結果として中の画像のobject-fitも道連れになって無効化されます。

画像を<a><span>などのタグで包んでトリミングする際は、「親要素に対してdisplay: block;またはdisplay: inline-block;を指定し、幅と高さを持てる状態に変更すること」です。

⭕️ aタグやspanタグを使うなら、必ず「display: block」で箱にしろ!

❌ 罠(spanがインラインのまま)
幅・高さ・はみ出し防止がすべて無視され画像が暴走

風景

⭕️ 成功(display: block を追加)
spanが「箱」になり、150pxの正方形に綺麗に収まる

風景
/* ❌ インライン要素に幅と高さを指定してしまう */
span.link-fail {
  width: 150px; /* 🚨 インライン要素だから効かない!無視される */
  height: 150px;
  overflow: hidden; /* 🚨 これも効かず、画像がはみ出す */
}

/* ⭕️ 親要素を block(または inline-block)に変える! */
span.link-success {
  display: block; /* 💡 これで span が立派な「箱」になる */
  width: 150px;
  height: 150px;
  overflow: hidden;
}
span.link-success img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* 💡 親が箱になったので、完璧に効く! */
}
HTMLコード表示
<div class="of-inline-v2-wrapper">
  
  <p class="of-inline-v2-caption">⭕️ aタグやspanタグを使うなら、必ず「display: block」で箱にしろ!</p>

  <div class="of-inline-v2-demo-area">
    
    <div class="of-inline-v2-item">
      <p class="of-inline-v2-label" style="color:#dc3545;">❌ 罠(spanがインラインのまま)<br><small>幅・高さ・はみ出し防止がすべて無視され画像が暴走</small></p>
      
      <div class="normal-text-context">
        <span class="inline-v2-trap">
          <img src="https://picsum.photos/id/1012/600/300" alt="風景" class="img-trap">
        </span>
      </div>
    </div>

    <div class="of-inline-v2-item">
      <p class="of-inline-v2-label" style="color:#0d6efd;">⭕️ 成功(display: block を追加)<br><small>spanが「箱」になり、150pxの正方形に綺麗に収まる</small></p>
      
      <div class="normal-text-context">
        <span class="inline-v2-success">
          <img src="https://picsum.photos/id/1012/600/300" alt="風景" class="img-success">
        </span>
      </div>
    </div>

  </div>

  <div class="of-inline-v2-code-area">
    <span class="hl-comment">/* ❌ インライン要素に幅と高さを指定してしまう */</span><br>
    <span class="hl-blue">span.link-fail</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">150px;</span> <span class="hl-comment">/* 🚨 インライン要素だから効かない!無視される */</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">overflow:</span> <span class="hl-red">hidden;</span> <span class="hl-comment">/* 🚨 これも効かず、画像がはみ出す */</span><br>
    }<br><br>

    <span class="hl-comment">/* ⭕️ 親要素を block(または inline-block)に変える! */</span><br>
    <span class="hl-blue">span.link-success</span> {<br>
      <span class="hl-green">display:</span> <span class="hl-red">block;</span> <span class="hl-comment">/* 💡 これで span が立派な「箱」になる */</span><br>
      <span class="hl-green">width:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">150px;</span><br>
      <span class="hl-green">overflow:</span> <span class="hl-red">hidden;</span><br>
    }<br>
    <span class="hl-blue">span.link-success img</span> {<br>
      <span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">height:</span> <span class="hl-red">100%;</span><br>
      <span class="hl-green">object-fit:</span> <span class="hl-red">cover;</span> <span class="hl-comment">/* 💡 親が箱になったので、完璧に効く! */</span><br>
    }
  </div>

</div>
CSSコード表示
.of-inline-v2-wrapper {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.of-inline-v2-caption {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #198754;
  text-align: center;
}

.of-inline-v2-demo-area {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  justify-content: center;
  align-items: flex-start; /* 縦に伸びないようにする */
  background-color: #e9ecef;
  padding: 30px 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
  margin-bottom: 20px;
}

.of-inline-v2-item {
  width: 250px; /* 画像が暴走した時の最大幅を制限しておく */
  text-align: center;
}

.of-inline-v2-label {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin-bottom: 15px;
  line-height: 1.5;
  height: 40px;
}

/* Flexboxの影響を断ち切るための通常のブロックコンテナ */
.normal-text-context {
  display: block !important;
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  border: 1px dashed #adb5bd;
}

/* =❌ 罠:spanをインラインに強制= */
.inline-v2-trap {
  display: inline !important; /* 💡 絶対にインラインにする */
  width: 150px !important;    /* 🚨 効かない */
  height: 150px !important;   /* 🚨 効かない */
  overflow: hidden !important;/* 🚨 効かない */
  border: 4px solid #dc3545 !important;
}

/* 罠の中の画像:親の幅(150px)が効かないので、外側のブロック要素(200px以上)まで広がってしまう */
.img-trap {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* =⭕️ 正解:spanにdisplay: blockを指定= */
.inline-v2-success {
  display: block !important; /* 💡 箱にする */
  width: 150px !important;   /* 💡 効く! */
  height: 150px !important;  /* 💡 効く! */
  overflow: hidden !important;/* 💡 効く! */
  border: 4px solid #0d6efd !important;
  margin: 0 auto;
}

/* 成功の中の画像:親が150pxの箱なので、ピッタリ収まる */
.img-success {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* =コード解説エリア= */
.of-inline-v2-code-area {
  background-color: #282c34;
  color: #abb2bf;
  padding: 20px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
  overflow-x: auto;
  text-align: left;
}

.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }

要素の性質を変更するdisplayプロパティの使い方を詳しく知りたい人は「【CSS】displayの種類は?flexやinline-blockの違い」を一読ください。

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • object-fit<img><video>要素の中身を、指定した枠に収めるかを決めるプロパティである。
  • 適用させるには、対象の要素自体にwidthheight(またはaspect-ratio)の指定が必須である。
  • サムネイルや背景写真には枠を埋め尽くすcover、ロゴやバナーには見切れを防ぐcontainを用途に合わせて使い分ける。
  • width: 100%;aspect-ratioobject-fit: cover;の3点セットでレスポンシブ対応のサムネイルが実装できる。
  • 動画(<video>)にも有効であり、指定することで比率による黒帯(レターボックス)を解消できる。
  • CSSの背景画像(background-image)に対しては無効であり、代わりにbackground-sizeを使用する。
  • トリミングの基準位置(顔を切らない等)を調整するにはobject-positionを併用する。
  • インライン要素(aspan)で囲んで枠にする場合は、display: blockまたはinline-blockを指定してサイズを持たせる必要がある。

よくある質問(FAQ)

object-fit: cover;とcontain;の違いは何ですか?

画像を「枠」にどのように収めるかが異なります。

coverは、画像の縦横比を保ったまま、指定した枠を「覆い尽くす」ように拡大・縮小します。

containは、縦横比を保ったまま枠の中に「画像全体がすべて収まる」ように調整されます。

object-fitを指定したのに全く効かないのはなぜですか?

最も多い原因は、対象の画像(<img>)に widthheightが指定されていないことです。

object-fitは「決められた枠のサイズ」に対して中身をどう調整するかを決めるプロパティです。

高さを指定せずautoのままにしていると、画像が本来の比率で伸びてしまうため、トリミングする「枠」が存在せず、プロパティが無効化されてしまいます。

幅と高さ(またはaspect-ratio)をセットで指定してください。

背景画像にobject-fitは使えますか?

いいえ、使えません。

object-fitは、HTMLタグとして配置された<img><video>要素自体に対して機能するプロパティです。

CSSのbackground-imageで設定した背景画像のサイズやトリミング方法を調整したい場合は、代わりにbackground-size: cover;background-size: contain;を使用してください。

coverを使うと人物の顔が見切れてしまいます。位置の調整はできますか?

はい、object-positionプロパティを併用することで調整可能です。

object-fitはデフォルトで画像の中央(center)を中心にトリミングを行います。

人物の顔を残したい場合は、合わせてobject-position: top;を指定することで、画像の上端を基準に切り抜くことができ、顔が見切れるのを防ぐことができます。

パーセンテージ(例: 50% 20%)での微調整も可能です。

object-fitは画像(img)以外にも使えますか?

はい、使えます。

実務で特に使われるのが<video>(動画)要素への適用です。

Webサイトのファーストビューなどで動画を全画面背景として流す際、単に幅と高さを100%にするだけだと上下や左右に黒い帯(レターボックス)が出てしまいます。

ここで<video>タグにobject-fit: cover;を指定することで、黒帯を消し去り、画面いっぱいに動画を敷き詰めることができます。

CONTACT

サイト制作でお困りの人はお気軽にご連絡ください。
どんなお悩み事も丁寧に返信させて頂きます。

WordPress移行
Webサイトを公開しよう!

「どのサーバーを選べばいいか分からない…」そんな悩みを解決!
WordPressデビューに最適なサーバーを徹底比較しました。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次