object-fitを使って簡単にサムネ表示やメインビジュアルをスタイリングする

この記事は最終更新から4年以上が経過しています。情報が古くなっている可能性があります。

こんにちは、しばです。
ぱっと見では同じレイアウトでも、コーディング方法がいくつかあることって多いですよね。

メインビジュアルやサムネイル表示等で画像の見栄えを整えたいとき、私は背景画像やpositionプロパティに頼ることが多かったんですが、そこで出会ったのがこのobject-fitというプロパティです。

画像をトリミングできるプロパティだそうで、どうやらこれまでcssで何行も書いていたレイアウトがかなりシンプルに書けそう…

ということで、よくあるobject-fitを使って実際に色々と試してみました。試した感想や使い方について書いていきます。

object-fitとは?

object-fitは、img要素やvideo要素などの置換要素を、ボックスにどのようにはめ込むかを指定する際に使用するプロパティです。

img要素やvideo要素そのもののサイズに対して中身の写真や動画の表示方法を指定することで画像のトリミングができます。

各設定値ごとの挙動はこちらのサイトが参考になりました。

IMG要素のスタイリングの自由度がかなり上がりましたね…
background-size感覚で使えそうです。

実際に使うシチュエーションを考えてみると、

  • メインビジュアルでアスペクト比と違った見せ方をさせたいとき
  • サイズがばらばらの画像をサムネイル一覧として並べたいとき

ここらへんのスタイリングに便利そうだったので、実際にobject-fitで試してみました。

object-fitでスタイリングしてみる

メインビジュアルの天地中央寄せ

PCレイアウトのメインビジュアルの見せ方のひとつに、上下左右中央を中心点として、特定の幅(画像サイズ等)以下は画像が左右にコンテンツからはみでて、特定の幅以降は拡大しながら上下にはみでていくというパターンがあると思います。

こんな感じの動きをさせたい時どう書くか試してみます。

まず、これまでよく使用していたpositionを使った書き方。

.img {/*img要素を包含するdiv*/
	width:100%;
	margin: 0 auto;
	min-height: 450px;
	overflow:hidden;
	position: relative;
}
img {
    position: absolute;
    width: auto;
    height: auto;
    min-width: 100%;
    min-height: 100%;
    -webkit-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
    top: 50%;
    left: 50%;
}

Demo
※スマホ時はアスペクト比を保持して縮小してます。

これを、object-fitを使って書いてみます。

img {
    height:450px;
    width: 100%;
    object-fit: cover;
    vertical-align: top;
}

Demo

包含するdivいらず…だと..(°Д°;)
ものすごくシンプルにかけました。

サムネイルを横並びにする

ニュースのサムネイルを横並びで一覧表示させたい時などはよくあると思います。WordPressならサムネイルの画像サイズは統一できますが、サイズがばらばらな画像を並べなくてはいけないというケースもありますよね。

これまでの書き方だと以下のようにpositionで書いたりしていました。

.box {/*包含する要素にdisplay:flexを適用*/
	width: 25%;
}
.box .img {
	position:relative;
	width:100%;
	padding-top: 58%;
	overflow: hidden;
}
.box .img img {
	position: absolute;
    width: auto;
    height: auto;
    min-width: 100%;
    min-height: 100%;
    -webkit-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
    top: 50%;
    left: 50%;
}

Demo

object-fitだとこう書けるようになります。

.box {/*包含する要素にdisplay:flexを適用*/
	width: 25%;
}
.box .img img {
	width: 100%;
    height: 14.3vw;
    object-fit: cover;
}

Demo

padding-topを使わないため高さの指定方法は変わりますが、ぱっと見で分かりやすくなった気がします。

しかも、positionの方は指定のサイズに足りない画像は自動で拡大されますが、大きすぎる画像は指定のサイズに合うよう縮小してくれていません。(書き方が悪い可能性…)

さくっと書ける上に、それぞれのサムネ画像のサイズ・アスペクト比を尊重した表示ができるのはいいですね!

IE/Edge対応が必要

便利なobject-fitですが、2018/11/27現在、IE未対応・Edge一部未対応という状況です。


引用元)Can I use

便利な分めちゃくちゃ惜しい…(ノД`)
と思っていたら、E/Edgeに対応させられるプラグインがありました。

3KBの軽いファイルを読み込んでjsとcssに1行ずつ記述するだけ。svgのIE対応レベルでさくっと導入できます。
具体的には次の2つの作業を行います。

1. プラグインのjsを読み込ませて、関数を呼び出す

<script src="https://cdnjs.cloudflare.com/ajax/libs/object-fit-images/3.2.4/ofi.min.js"></script>
<script>objectFitImages('.box .img img');</script>

読み込んでいるファイルはCDNの例です。
呼び出している関数は、全体の画像に適用したいならobjectFitImages(); のように引数なしで、特定の画像を指定したいなら上記のように引数にセレクタを書くことができます。

2. cssに追記

object-fit: cover;
font-family: 'object-fit: cover;';/*IE用*/

object-fitプロパティの後ろに、font-familyプロパティでobject-fitを書きます。これを書くことで、プラグインがIE/Edgeでもよしなに表示させてくれます。

ということで、先ほどのデモをIE/Edge対応したものがこちら。

MVdemo

サムネdemo

綺麗にIE/Edgeでも表示されるようになりました!

よりシンプル&セマンティックなコーディングができる

個人的にIMG要素をもっと柔軟にスタイリングできたらいいのに!と感じることが多かったので、object-fitはセマンティックなHTMLマークアップ、シンプルなcssコーディングをする上で非常に強い味方だなぁと感じました。

IE/Edge対応用プラグインも他とまとめて結合・圧縮すれば、ほとんど負荷はかからなそうなので、是非積極的に使っていきたい…!

以上、「object-fitを使って簡単にサムネ表示やメインビジュアルをスタイリングする」でした。