均等な大きさのサムネイルの中にいろんな画角の画像をピッタリ表示させる

商品写真やプロフィール写真などの一覧ページで、DBから引っ張ってきた縦長横長どちらかわからない画像を全て同じ矩形内にピッタリ表示を揃えたい場合、案外面倒ですよね・・・
最近これが必要な案件が立て続けにあったので後々楽できるようにjQueryプラグインにしておきました。
異なる画角の画像を均等なサイズで表示させる方法
バラバラのサイズの画像をとある矩形の横幅いっぱいに揃えて表示する場合、max-widthで横幅と、あとheight: autoを指定しておくのが一番手っ取り早いのですが、想定外の横長の画像とかが入って来ると下に余白ができてしまいます。

静的なページではある程度画像サイズを均一にしておくなどしていくらでも対応可能なのですが、動的なページ制作の場合では、バラバラの画角の画像が入ってくる事も想定されるので、思った通りの表示にならない事が多いです。
なのでCSSで綺麗に表示を整えようと思ったらimg要素の大きさを変える方法では無くて、親の要素に背景画像として指定してやる必要があります。
ul.thumb
li
background-image: url('画像のパス')
width: 100px
height: 100px
background-position: center center
background-repeat: no-repeat
background-size: coverこれならどんな大きさの画像が入っても中心から縦横どちらかの最大幅で矩形内に一杯一杯に表示させてくれます。

CSS内に画像のパスを書きたくないのでJSでHTMLを書き換える
前述の方法を使用するとcssの中に画像のパスを指定するか、もしくはbackground-imageだけHTMLに直書きするかしなければならないので、通常リストで画像を並べる時と比べてマークアップが大きく異なってしまい、後から入るデザインの修正に対してあまり柔軟では無くなってしまいます。
cssに複数の画像のパスを入れるのは面倒そうなのでやるとしたらhtmlを書き換えてこんな感じになるかと思われます。
<ul class="thumb">
<li style="background-image: url('画像のパス')"></li>
<li style="background-image: url('画像のパス')"></li>
</ul>でも、できればHTMLの文章構造はデザインに依存しない方が良い気がするのでいつも通りこうやって書いておきたいですよね・・・
<ul class="thumb">
<li><img src="画像のパス"></li>
<li><img src="画像のパス"></li>
</ul>理想としてはマークアップは従来通りliタグなどに入ったimgタグのままの記載しておきたいのですが、このマークアップの状態で画像をフィットさせようと思ったら現状ではobject-fitくらしか方法が無いと思うのですが、それだとchromeくらいでしかまともに表示されないサイトになってしまいます。
ので、やはりここは一部jsで工夫して表示させる必要があります。
jsでimgの画像のパスをbackground-imageに書き直そうと思ったら
入れ子になっているimg要素から画像のパスを取得して、liタグに直接cssを指定すれば良いだけです。
$('li', 'ul.thumb').each(function(i, el) {
$(el).css({
'background-image': 'url('+$('img', el).attr('src')+')',
});
});これでcssファイルの中に画像のパスを書く事を回避できました。
jQueryプラグインにしておいた
毎回おんなじjs書くのも面倒なのでjQueryプラグインに纏めておきました。
jsでcssを書くのはあんまり好きでは無いのですが、この場合にはbackground-imageの部分は結局js上で書く事になるし1行も4行もそんなに変わらないかなと思ったので必要最低限のCSSだけはjsで指定しています。
var param;
$element.each(function(i, el) {
param = {
'background-image': 'url('+$('img', el).attr('src')+')',
'background-position': 'center center',
'background-repeat': 'no-repeat',
'background-size': 'cover'
};
if(plugin.settings.width) param.width = plugin.settings.width;
if(plugin.settings.height) param.height = plugin.settings.height;
$(el).css(param);
$('img', el).css({
'opacity': 0
});
});こんな感じで呼び出します。
$('li', 'ul.js-thumbs').thumbfit();横幅と縦幅は親要素のサイズに合うようになっているので指定はいらないのですが、jsからも指定できるようになっています。
画像を背景で表示するように変更するので元のimg要素がいらなくなり、非表示にする必要があるのですが、このプラグインではdisplay: noneにせずにopasity: 0にしています。
1
あとサムネイルに使っている猫画像は placekitten.com というURLで指定したサイズの画像を返してくれるWEBサービスを使用しています。
- ブラウザ上では他のimg要素とできる限り同様の扱いができた方が良いと思ったのでこうしています。ドラッグできない方が良かったらdisplay:noneに変更すれば良いかと思われます。 ↩
