Site icon Tips Note by TAM

サイズの決まってない画像を決まったサイズの表示領域に上下左右中央に表示する

決まった寸法の領域に、縦横比もサイズもバラバラの画像を「うまいこと」表示しないといけないなんてことないでしょうか。
HTML + CSSで地味に苦労する上下左右中央とサイズの調整、未だに一発書きが出来ません。
flexboxなどの新しいプロパティが使えるようになりましたが、Internet Explorerのことを考えるとなかなか手放しでは使えないのが現状です。

  1. 縦横どちらも規定より小さい画像は上下左右中央に原寸表示
  2. 縦横比が表示領域と異なり、規定よりもサイズが大きい画像は長辺を縮めて最大幅に合わせて縮小し、上下もしくは左右の中央に表示

画像をトリミングも引き伸ばしもせずに、原寸もしくはそれ以下で全部表示するということですね。
この2つを実現し、なおかつ画像を背景画像ではなくimg要素として記述するコーディングをご紹介します。
今回はInternet Explorer 10にも対応しています。

横600pxのコンテナ内に200pxずつのボックスが3つ並んでいて、ここに高さ90pxまでで画像を前述のような条件で表示したいとします。
つまり、それぞれの画像を表示できる領域は縦横比9:20です。

今回用意した画像はそれぞれ

  1. 横300px 縦100px 縦横比1:3
  2. 横200px 縦400px 縦横比2:1
  3. 横50px 縦50px 縦横比1:1

となっています。一つとして縦横比は一緒ではありません。
また、3の画像は表示領域の横200px 縦90pxどちらの辺よりも小さい画像です。
並べると以下のようになります。

これを横200px 縦90pxの表示領域に収めた場合をSketch.appで作図してみました。

正しく出来たらこのように表示されるはずです。
ではやっていきましょう。

まずはHTMLです。このようにマークアップしました。

特に変わったことはしていませんね。
次にSCSSです。

.thumbnail.imageでサイズの指定をしています。
幅は親要素に追従します(今回は.item)。
高さは画像がmax-heightとheightによって原寸もしくは親要素いっぱいに広がります。
その親要素の.innerはそのさらに親要素の.thumbnailいっぱいに広がっています。
td要素と同じふるまいをするdisplayプロパティに設定されているため、vertical-alignやtext-alignによって中のインライン要素が整列されています。これにより、上下左右中央が実現されます。
.thumbnailには高さが与えられているため、これ以上に伸びることはありません。

画像はvertical-alignプロパティをbottomに設定しておかないと、やや上に浮いてしまいますのでご注意ください。
また、table-layoutプロパティでセルの大きさを固定しておかないと、子要素が決まった大きさを持たないため一部のブラウザで高さが算定できずにつぶれてしまう場合があります。

JSFiddleで確認してみましょう。
「Edit Fiddle」からplacehold.jpのプレースホルダー画像のサイズを変更してみると、わかりやすいかとおもいます。

いかがだったでしょうか。.thumbnail .inner .imageのクラスセレクタに記述されているスタイル群が一番重要ですので、そこをコピペしてもらってコメントのついているところの高さを変更してもらえれば大丈夫です。案件ではmixinを作って使い回しています。
しかしもっと簡単にできそうな気もするんですが、やっていきましょう。

flexboxを使った上下中央レイアウトはこちらの記事もどうぞ

【JSいらず】CSS3 のFlexbox を使った、イマドキの上下中央配置レイアウト

それではまた。