Photoshopいらず!CSSで画像を中央トリミングする方法(レスポンシブ対応)

最近、会社のサイトをリニューアルする機会があったんですが、サムネイルのサイズがみんなバラバラ!ってことがあったんですよね。今まではそれを横幅だけ揃えて高さはバラバラなまま表示してたりして、なんだか統一感のないデザインだったんですが、そんな悩みを解決してくれるcssを覚えたので、メモとして書き残しておきます!
画像の可変幅にも対応できているので、レスポンシブWebデザインにも使えますよ!
サムネイルの画像サイズがみんなバラバラ・・・
サムネイルの画像サイズがバラバラだと、どうしても表示に統一感がなくなってしまいますよね。Pinterestのような、サムネイルのバラバラ感を逆に活かしたレイアウトであればいいのですが、使い所が限られてきます。

かといって、複数個ならまだしも何百、何千とある画像をリサイズするのは手動でも自動でも大変…!というわけで、cssで中央部分をトリミングして同じサイズで表示してみましょう!
CSSで画像を中央でクロップして同じサイズで表示する方法
以下が実装用のコードです。「CSS」のタブをクリックして確認してみてくださいね。
See the Pen CSSでサイズがバラバラな画像を中央でトリミングして表示(レスポンシブ対応) by 彩 (@maritime_color) on CodePen.
実装のポイント
画像をトリミング範囲となる外枠で囲む
まずは画像を外枠で囲います。この枠のサイズがトリミング範囲となるため、枠に対してoverflow: hidden;を設定すると、枠からはみ出た部分が非表示になります。

画像は枠に対して以下のように絶対指定で中央配置されているため、ちょうど画像の真ん中でトリミングしたように表示されるというわけです。
/* 画像を上下左右に中央配置する(絶対指定) */ position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%);
レスポンシブに対応するには、外枠の高さをpaddingで指定
画像自体を可変にするのであれば、幅を100%に指定してあげるだけで比率を保持したまま自由に伸縮できます。…が、画像を囲っている枠を可変にするためには、枠にpadding-top(またはpadding-bottom)を指定して高さを出してあげる必要があります。
今回は、画像を4:3の比率でトリミングしているため、以下のようにpadding-topの値を75%に指定しています。
width: 100%;/* トリミングしたい枠の幅 */ padding-top: 75%;/* トリミングしたい枠の高さ */
この75%という数値は、画像の比率にもとづいて計算されています。比率4:3の画像の、横幅に対する高さの割合を求めればいいので、「高さ÷幅×100%」で答えが出ます。たとえば、正方形にしたい場合は、幅に対する高さの割合は100%、と考えると簡単ですね!

計算方法がよくわからない方は、Design Spiceで丁寧に解説してくれていますのでご参考までに!
ちなみに、トリミングするサイズが固定であれば、以下のようにサイズを指定してあげればOKです。
width: 200px; height: 200px;
注意点
画像の比率がトリミング範囲と違いすぎると余白が生まれる
ここでは、非表示の部分の方が大きくなってしまうのを防ぐため、画像にmax-widthとmax-heightを指定して画像の最大サイズを定めています。
/* 画像の最大サイズは枠の1.5倍まで */ max-width: 150%; max-height: 150%;
つまり、外枠のサイズより画像が大きい場合でも、画像は枠の1.5倍のサイズ以上は大きくなりません。

最大サイズを定めることによって、トリミングする範囲をできるだけ小さくすることができますが、大幅に異なる比率の画像を入れてしまうと余白が生まれてしまうのです。

枠からはみ出た部分は本当にトリミングされたわけではない
Photoshopを使ったように枠からはみ出た部分がカットされてとっても便利な手法ですが、はみ出た部分は本当にトリミングされたわけではなく、CSSで非表示になっているだけです。
なんとなく画像をドラッグしてみた時や、スマホでリンクをタップした時に元画像の形が見えてしまい、ちょっとカッコ悪い思いをすることもあります。ま、気にしなければ支障はないですけどね。

また、表示サイズよりも大きい画像を読み込むと読み込み速度が遅くなることもありますし、先述したように意図した表示にならない可能性もあります。そういった注意点をふまえた上で、この方法がお役に立てればいいなーと思います。
2018年4月14日 追記
スマホなら、リンクをタップした時に出るハイライトカラーを無効化する方法がありました。aタグに以下の一行を追加するだけです!
-webkit-tap-highlight-color: transparent;
これなら元の画像の形がバレてしまって恥ずかしい思いをすることはなくなります。ただし、タップ時のハイライトカラーは、ユーザーに「自分がリンクを押した」という感覚を教えてくれるとても重要な要素だと思うので、よく考えて使いましょう!
「transform」はIE10以上に対応!
今回のCSSのキモは「transform」というプロパティですが、こちらはIE10以上に対応しています!IE9にも「-ms-」というベンダープレフィックスをつければ対応できるようですが、私が確認した限り、レイアウトがくずれてしまったようなので、IE10以上と記述しました。個人的にはIE11に対応できていれば最近では問題ないかなと考えています。
その他のブラウザでもほぼ問題なしです。安心ですね!
今回の記事は、以下のサイトを参考に書かせていただきました!どちらもcssで画像をトリミングすることのメリット・デメリットなどをわかりやすく解説してくださっています。ありがとうございました〜!
さいごに
最近はブラウザの対応状況などをあまり気にせず、どんどんcssで色々なことができるようになって本当にうれしいです。もしバラバラな画像の処理で悩んでいる方がいたらぜひ使ってみてください!以上、彩でした!
この記事をシェアする!
2件のコメント
もし何かコメントをいただければ幸いです。また、ご指摘等も大歓迎です。
よろしくお願いします。(※Eメールアドレスは公開されません)
はじめまして。
こちらの記事を参考にさせていただきます!
突然で申し訳ございませんが、1点質問なのですが、画像の横並びの数を増やすにはどうすればよろしいのでしょうか?
記事を読んでいただいてありがとうございます!
画像の横並びを増やすには、liのwidthの数値をいじってあげると変わります!
たとえば3つ並びにしたい場合はためしにwidthを30%とかにしてもらうと変わると思います。
数値は100を並べたい数で割ると出すことが出来ます。
例えば、2つ並びは単純に100÷2=50で、50%にすれば2つ並びになります(ソースコードでは48%となっていますが、両端にmarginで1%の余白を設けているためです)。
余白を設けなければ、3つ並びなら100÷3で約33%。4つ並びなら25%ですね。
わかりづらい説明で申し訳ないのですが、解決できましたでしょうか・・・!