LoginSignup
62

More than 1 year has passed since last update.

サイズがバラバラな画像をレスポンシブで縦横比を揃えて表示させる

Last updated at Posted at 2019-08-29

追記(2021/10/14)

この記事のやり方は古いやり方です。
IE や過去バージョンのブラウザに対応したい場合に参考にしてください。

今は aspect-ratio プロパティを使ってくださいね。
参考:CSSのaspect-ratioプロパティがすべてのブラウザにサポートされました、画像をアスペクト比で実装する今までとこれからの実装方法 | コリス

やりたいこと

  • サイズがバラバラな複数枚の画像を表示サイズを合わせて表示したい。
  • レスポンシブで縦と横の比率も揃えたい。
  • 画像のトリミングは縦方向も横方向も中央部分が表示できれば良い。

CSS で画像をトリミングする方法

CSS で画像をトリミングするには…で思いつくのは2パターン。
ただしどちらも今回のやりたいことが達成できない:sob:

object-fit を使う方法

object-fit - CSS: カスケーディングスタイルシート | MDN

CSS の object-fit プロパティは、置換要素、例えば <img><video> などの中身を、コンテナーにどのようにはめ込むかを設定します。

今やりたいものだと以下のように書く。

img {
  object-fit: cover;
  width: 200px;
  height: 150px;
}

cover という値は、縦横比を維持したまま要素のボックスに収まるように拡大縮小されるとのこと(上記 MDN より)

  • 決められたサイズではみでた部分を非表示にはできる。
  • 縦も横もピクセル数で指定する必要があるのでレスポンシブにならない。

親要素で囲う方法

.image-trim {
  position: relative;
  overflow: hidden;
  padding-top: 60%; /* 比率 */
}
.image-trim img {
  width: 100%;

  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: auto;
  transform: translate(-50%, -50%);
}
  • 親要素で縦方向(高さ)を横方向(幅)の何パーセントと指定することでレスポンシブできる
  • 縦長画像はボックスいっぱいにできる。
  • ただし、横長画像は上下方向に余白ができてしまう。

こんな感じ(薄グレーの地が親要素のボックスのサイズです)
スクリーンショット 2019-08-30 5.28.29.png

解決方法は上記2パターンをかけ合わせ

こんな感じ。

.image-trim {
  position: relative;
  overflow: hidden;
  padding-top: 60%; /* 比率 */
}
.image-trim img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  object-fit: cover;
}

サンプル

サンプルとしてサイズがばらばらな画像を用意してみた。

スクリーンショット 2019-08-29 16.53.27.png

(ありえないほどめちゃくちゃだ……)
しかし、縦長の画像も横長の画像も小さいサイズだってご覧のとおり!

スクリーンショット 2019-08-29 16.56.01.png

小さいサイズの画像も拡大されてガビガビに。
レスポンシブかどうかは以下の Codepen でブラウザのウインドウ幅を変えてみてください。

See the Pen responsive trimming image by Beco (@becolomochi) on CodePen.

なぜそうなるのか

よく考えてみれば簡単な話で、

  • img に object-fit:cover を指定し、縦横100%を指定することで親要素の大きさ依存でトリミングできる。
  • 親要素の大きさの指定がレスポンシブになっている。
  • 位置を絶対値指定することで枠内に収まる。

トリミング位置を変えたい場合は

「トリミング位置を中央じゃなくて他がいい!」というときは、 object-position で変えることができる。

object-position - CSS: カスケーディングスタイルシート | MDN

object-position: left top; /* 左上 */
object-position: 100px 50px; /* 横方向100px 縦方向50px */

初期値が 50% 50% ということで特に指定しなければ縦方向横方向ともに中央になる。

参考

解決の糸口になったCodepen (ありがとうございます…)
Responsive image with picturefill and object-fit

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62