object-fit のおさらい

  • プロダクション
object-fit のおさらい

目次

object-fit is 何

object-fit は、画像や動画がどんな大きさでも表示領域にうまくフィットさせてくれる、便利な CSS プロパティです。唯一未対応だった Internet Explorer が引退し、このプロパティを使う機会も増えてくると思いますので、あらためて機能や使い方を復習しておきたいと思います。

画像につきまとう「アスペクト比」

従来、サムネイル画像の寸法は表示エリアの縦横比に合わせてあらかじめ整えておく必要がありました。デザインパターンが複数ある時は、その数だけサムネイル画像を準備しなければいけないなんてことも……。

  • 使われる場所によってサムネイルのアスペクト比はさまざま
    使われる場所によってサムネイルのアスペクト比はさまざま

画像の縦横比を気にしなくてよくなる

object-fit を使えば、このような制約から自由になります。表示エリアがどのような寸法・縦横比だろうと「イイ感じに」画像をフィットさせてくれる救世主が object-fit です。background-size: cover や background-size: contain と同じことが <img> や <video> でもできる、と言えば直感的に伝わりやすいでしょう。

基本的な使い方

<img src="sample.jpg" alt="サンプル画像" class="example" />
.example {
    width: 400px;      /* ① */
    height: 400px;     /* ① */
    object-fit: cover; /* ② */
}

まず、object-fit させたい img には、必ず width と height を持たせます(①)。object-fit は「制約されたエリアに対して画像をどうはめこむか」を操作するプロパティですので、制約がないと機能しません。

次に object-fit プロパティとキーワード値を設定して完了です(②)。ここでは cover を指定しています。たったこれだけ。

キーワード値

では、それぞれのキーワード値の働きについて見ていきましょう。以下の例はいずれも、「アスペクト比 16:9 の画像データ」を「正方形のエリア」に表示しようとしています。

cover

おそらくもっともよく使われるであろう値。background-size: cover と同様、表示エリアになるべく余白なく画像を表示しようとし、はみ出してしまう部分はトリミングします。画像の一部が欠けても問題ないサムネイルやキービジュアルなどに適しているでしょう。

contain

background-size: contain と同様、なるべく表示エリアいっぱいに画像全体を表示しようとする時に、足りない部分を余白にします。
部分的にでも情報が欠けてはいけない商品画像や人物ポートレートなどに適しているでしょう。

fill

画像を変形させてでも画像全体を表示エリア全面に表示しようとします。object-fit なしに width と height に 100% を指定したのと同じ結果になります。

none

画像はピクセル等倍で表示されます。エリアに対してはみ出してしまう場合はトリミングされ、足りない場合は余白にします(グローバル値の unset とは異なります)。

scale-down

画像はピクセル等倍で表示されますが、はみ出してしまう場合だけ contain と同様に縮小されます。画像が表示エリアより小さい時は none と同様に余白となります。

unset

object-fit を解除するグローバル値です(none と紛らわしいので念のため)

【デモ】object-fit のキーワード

実践的な使い方

<div class="container -square">
    <img src="sample.jpg" alt="サンプル画像" />
</div>
 
<div class="container -landscape">
    <img src="sample.jpg" alt="サンプル画像" />
</div>
 
<div class="container -portrait">
    <img src="sample.jpg" alt="サンプル画像" />
</div>
.container {
    max-width: 400px;
    max-height:400px;
}
 
.-square {
    aspect-ratio: 1/1;
}
 
.-landscape {
    aspect-ratio: 16/9;
}
 
.-portrait {
    aspect-ratio: 9/16;
}
 
.container > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

こちらは親要素で表示エリアの寸法を決めてしまう例です。親要素がどんなアスペクト比でも img のスタイルはひとつで事足りるのが利点です。

様々なバリエーションを持つコンポーネントや、デバイスごとに異なるデザインを持つレスポンシブなコンポーネントにも柔軟に対応するには、こうした方法もあります。

【デモ】アスペクト比による変化

応用的な使い方

<div class="container">
    <img src="sample.jpg" alt="サンプル画像" class="background" />
    <img src="sample.jpg" alt="サンプル画像" class="foreground" />
</div>
.container {
    width: 400px;
    height: 400px;
    position: relative;
    overflow: hidden;
}
 
.container>img.background {
    width: 420px;
    height: 420px;
    margin: -10px;
    object-fit: cover;
    filter: blur(5px) brightness(0.5);
}
 
.container>img.foreground {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 0;
    left: 0;
    object-fit: contain;
}

こちらの例では object-fit の異なる画像を2枚重ね、上下・左右の余白を画像それ自身で埋めています。object-fit の設ける余白は透明であることを利用しています。

背景となる画像は CSS filter を使ってトーンを抑えています。その際、ぼかしの周縁がにじむので四方に10ピクセルずつオフセットしています。

【デモ】ぼかし背景をつけた画像

トリミング位置の調整

cover や none でエリア外にはみ出した部分がトリミングされる場合、その範囲はデフォルトでは上下・左右均等配分です。余分な軸の両端から中央に向かってトリミングされていくかたちになります。

でも、画像の注目点は真ん中ばかりとは限りませんよね。アシンメトリな構図の写真の場合、「右側だけトリミングしたい」とか「上寄りにトリミング」したいといったケースもあるでしょう。

そういう場合は object-position を併用することでトリミングの比率を偏らせることができます(ちなみに、background-size: cover ⇔ background-position でも同じことができます)。

【デモ】object-position でトリミング位置を調整する

object-fit と座標

object-fit を使用すると、時として表示エリアの座標系と画像データ自身の座標系が一致しなくなります。画像が表示エリア内でどのように変形されていても、MouseEvent.offsetX などの座標は通常の要素と同様に「要素の左上隅が原点」だからです。

画像の中に描かれている絵柄そのものが重要となるクリッカブルマップや虫眼鏡ツールなどでは、object-fit を介在させたとたん計算が無駄に複雑化しますので油断しないようにしましょう……。

【デモ】object-fit と座標取得

この記事の執筆者

G・I

テクノロジーソリューション事業部

この記事に関するご相談やご質問など、お気軽にお問い合わせください。

お問い合わせ

関連する記事

すべての記事を見る

タグ一覧