サムネイル一覧で画像のサイズがバラバラだと、レイアウトが崩れて見栄えが悪くなります。そんなときに役立つのが CSS の object-fit と object-position です。決まった枠に画像を流し込み、縦横比を保ったまま「うまくトリミングして表示する」ことができます。この記事では object-fit の5つの値の違いと、object-position での表示位置の調整方法を、実際に動くデモつきで解説します。
目次
object-fit とは
object-fit は、img や video などの「置換要素」が、自身に指定された枠(width と height)に対してどう収まるかを指定するプロパティです。たとえば縦長の写真も横長の写真も、すべて同じ正方形のサムネイルにそろえたい、といった場面で活躍します。
普通に img へ width と height を指定すると、画像が枠に合わせて引き伸ばされ、縦横比が崩れてしまいます。object-fit を使えば、縦横比を保ったまま枠に合わせて表示できるようになります。
基本の使い方
使い方はシンプルで、枠のサイズ(width / height)を決めた img に対して、object-fit を指定するだけです。もっともよく使うのは、枠を埋めるように画像をトリミングする cover です。
.thumbnail {
width: 200px; /* 枠の幅 */
height: 200px; /* 枠の高さ */
object-fit: cover; /* 縦横比を保ったまま枠を埋める */
}
これで、どんな縦横比の画像でも 200×200 の正方形に収まり、はみ出した部分は自動でトリミングされます。画像が引き伸ばされて歪むこともありません。
5つの値の違い
object-fit には5つの値があり、枠に対する画像の収まり方がそれぞれ異なります。まずは一覧で違いを把握しましょう。
| 値 | 動き |
|---|---|
fill | 枠いっぱいに引き伸ばす。縦横比は無視され、画像が歪むことがある(初期値) |
contain | 縦横比を保ったまま、画像全体が枠に収まるように縮小する。余白ができる |
cover | 縦横比を保ったまま、枠を埋めるように拡大する。はみ出した部分はトリミングされる |
none | リサイズせず元のサイズのまま表示する。枠より大きければはみ出す |
scale-down | none と contain を比べ、表示が小さくなるほうを採用する |
サムネイル表示でもっともよく使うのは cover、画像を見切れさせたくないときは contain、という使い分けが基本になります。
デモで違いを見比べてみよう
下のデモは、同じ横長の画像を 150×150 の同じ枠に入れ、それぞれ違う object-fit の値を指定したものです。グレーの背景は枠の範囲を表しています。fill は縦横比が崩れ、contain は上下に余白ができ、cover は枠いっぱいにトリミングされる、という違いが一目で分かります。CSS を書き換えて動きを試してみてください。
<div class="grid">
<figure>
<figcaption>fill</figcaption>
<img class="fill" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
<figure>
<figcaption>contain</figcaption>
<img class="contain" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
<figure>
<figcaption>cover</figcaption>
<img class="cover" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
<figure>
<figcaption>none</figcaption>
<img class="none" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
<figure>
<figcaption>scale-down</figcaption>
<img class="scale-down" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
<figure>
<figcaption>cover + object-position</figcaption>
<img class="cover-top" src="https://picsum.photos/id/1015/600/300" alt="サンプル画像">
</figure>
</div>
body {
margin: 0;
font-family: sans-serif;
color: #333;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 16px;
padding: 16px;
}
figure {
margin: 0;
}
figcaption {
font-size: 13px;
font-weight: bold;
margin-bottom: 6px;
color: #4f46e5;
}
/* すべての img を同じ枠(150x150)にそろえる */
.grid img {
width: 150px;
height: 150px;
border: 1px solid #ddd;
background: #f3f4f6; /* 余白部分が分かるように */
}
/* 枠いっぱいに引き伸ばす(縦横比が崩れる) */
.fill {
object-fit: fill;
}
/* 全体が収まるように縮小(余白ができる) */
.contain {
object-fit: contain;
}
/* 枠を埋めるように拡大(はみ出しはトリミング) */
.cover {
object-fit: cover;
}
/* 元のサイズのまま(枠より大きいとはみ出す) */
.none {
object-fit: none;
}
/* none と contain の小さいほうを採用 */
.scale-down {
object-fit: scale-down;
}
/* cover で表示位置を上寄せに */
.cover-top {
object-fit: cover;
object-position: top;
}
object-position で表示位置を調整する
cover は枠を埋めるように画像をトリミングしますが、初期状態では画像の中央を基準にトリミングされます。人物の顔が上のほうにある写真などでは、顔が見切れてしまうことがあります。そんなときに表示位置を調整するのが object-position です。
値は background-position と同じ書き方で、top / bottom / center といったキーワードや、50% 20% のようなパーセント、10px 20px のような長さで指定できます。最初の値が横方向、2つ目が縦方向です。
.thumbnail {
width: 200px;
height: 200px;
object-fit: cover;
object-position: top; /* 上側を優先して表示(下側がトリミングされる) */
}
上のデモの一番右にある「cover + object-position」が object-position: top を指定した例です。通常の cover とトリミングされる位置が変わっているのが分かります。顔が切れてしまうサムネイルなどで、見せたい部分を残すのに便利です。
object-fit が効かないときは枠のサイズを確認する
object-fit を指定したのに見た目が変わらない、という場合はほとんどがサイズ指定に原因があります。object-fit は「画像を枠にどう収めるか」を決めるプロパティなので、そもそも収める枠が定まっていないと効果が現れません。
width と height を指定していない
もっとも多いのが、画像に枠のサイズを指定していないケースです。width と height の両方を指定するか、aspect-ratio で縦横比を固定して、画像が収まる枠を作る必要があります。サイズを指定しない場合、画像は元のサイズで表示されるため、object-fit の値を変えても見た目が変わりません。
たとえば aspect-ratio を使うと、幅に応じて高さが自動で決まるレスポンシブなサムネイル枠を作れます。
.thumbnail {
width: 100%; /* 親要素の幅に合わせる */
aspect-ratio: 16 / 9; /* 高さは幅から自動計算され、枠が決まる */
object-fit: cover;
}
親要素ではなく画像自身に指定する
object-fit は、img や video といった要素自身に指定するプロパティです。画像を囲む div など親要素に指定しても効果はありません。トリミングしたい画像そのものに object-fit を書いているか確認しましょう。
まとめ
object-fit を使えば、サイズの異なる画像も、縦横比を保ったまま決まった枠にきれいに収められます。
- サムネイル表示には、枠を埋めてトリミングする
object-fit: coverが基本 - 画像を見切れさせたくないときは
containを使う - トリミング位置は
object-positionで調整できる - 効かないときは
width/heightかaspect-ratioで枠が決まっているか、画像自身に指定しているかを確認する
まずは img に width・height・object-fit: cover をセットで指定するところから試してみてください。