CSSだけで画像をトリミング!画像サイズに依存しないサムネイルの表示

Coding

CSSだけで画像をトリミング!画像サイズに依存しないサムネイルの表示

WEBサイトでは以下のような様々なサムネイル付きのカードや記事一覧がよく見られます。


このような記事一覧などは、WordPressなどのCMSで管理していることが多いです。
記事を投稿するたびに、サムネイルの画像を適性サイズにリサイズする手間や、レイアウト崩れを防ぐために、基本的にはどんなサイズの画像が登録されても綺麗に領域内に収まるようにあらかじめ組んでおく必要があります。
今回はCSSのみで、画像サイズに依存しないサムネイルを表示する方法をご紹介します。

カード型の記事一覧については、こちらの記事で解説しているので是非合わせて確認してみてください。

object-fitプロパティ

最も簡単な方法として、「object-fit」プロパティを使えば簡単に画像をいい感じにトリミングできます。

<div class="thum_box">
  <img src="img.jpg" alt="サムネイル">
</div>

.thum_box {
  width: 400px;
  height: 280px;
}
.thum_box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

object-fit とは img や video などを、コンテナーにどのようにはめ込むかを設定できるとても便利なプロパティです。
一言で言えば、画像としてHTMLに配置しているのに「background-size」と同じように扱うことができます。

ただし、object-fit はIEではサポートされていません
IEでも対応させるには、object-fit-imagesなどを利用する方法があります。

object-fit で設定できるプロパティは以下の通りです。

fill
初期値。コンテナー全体を画像で埋めます。画像とコンテナーのアスペクト比 ( 縦横比 ) が一致しない場合は、画像が引き延ばされるので歪む場合があります。

contain
画像のアスペクト比を維持したまま、コンテナーに収まるように拡大縮小されます。アスペクト比を維持するので、コンテナーのアスペクト比と一致しない場合は、余白が生まれその場合は縦横どちらも中央に配置されます。

cover
画像のアスペクト比を維持したまま、コンテナー全体を埋めます。
コンテナーのアスペクト比と一致しない場合は、縦横大きい方基準にトリミングされます。

none
画像のリサイズは行わずに、コンテナーの縦横中央に配置されます。
コンテナーより画像が大きい場合は、その分トリミングされます。

scale-down
画像のサイズに合わせて、「contain」と「none」のどちらかが適用されます。
コンテナーより画像サイズが大きければ「contain」、小さければ「none」となります。

backgroundプロパティ

画像を img では設置せずに、style属性で background-image として表示する方法です。
インラインでスタイルを記述することになってしまいますが、コンテナー全体を覆うことが可能になります。

<div class="thum_box" style="background-image: url(./img.jpg);"></div>

.thum_box {
  width: 400px;
  height: 280px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

positionプロパティとtransfromプロパティ

positionとtransfromを使い、画像をコンテナーの縦横中央に配置して、はみ出した部分を隠してトリミングする方法です。

<div class="thum_box">
  <img src="img.jpg" alt="サムネイル">
</div>

.thum_box {
  width: 400px;
  height: 280px;
  position: relative;
  overflow: hidden;
}
.thum_box img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

上記の場合は、max-width と max-height を100%にしているので、画像サイズがコンテナーよりも大きい場合は、縦横の大きい方を基準にし、アスペクト比が一致しないもしくは画像サイズがコンテナーよりも小さい場合は余白が生まれます。
max-width と max-height を指定しなければ、画像のリサイズは行われないので実際のサイズで中央に配置されます。

縦サイズを基準にトリミングする

縦サイズを基準に配置したい場合は、下記の記述になります。
width を auto、height を 100% に指定することで常に縦がコンテナーぴったりにしています。

.thum_box img {
  width: auto;
  height: 100%;
  max-width: none;
  max-height: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

横サイズを基準にトリミングする

横サイズを基準にしたい場合は、逆に width を 100%、height を auto に指定することで常に横がコンテナーぴったりにできます。

.thum_box img {
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: none;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

また、CSS の @supports と組み合わせれば、object-fit がサポートされているブラウザとそれ以外などで分岐させることも可能です。

.thum_box img {
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: none;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}
@supports (object-fit: cover) {
  .thum_box img {
    position: static;
    height: 100%;
    width: 100%;
    object-fit: cover;
    -ms-transform: none;
    -webkit-transform: none;
    transform: none;
  }
}

まとめ

CSSのみで、画像サイズに依存しないサムネイルを表示する方法をご紹介しました。
基本的にやっていることは中央に配置してはみ出た部分を隠すという作業です。
注意点として、画像自体のサイズを変更しているわけではないので、画像の容量などは変わっていません。サイトの表示速度低下にも繋がってくるので、やはり画像加工が可能であれば、ある程度適切なサイズへ加工したり圧縮することをおすすめします。

ですが、どんな画像が登録されても領域内に綺麗に収まるようにしておくことは必ずしておいた方が良いので、ご自身の状況にあった方法で対応してみてください。