大きさ・縦横比の違う画像の縦・横を均一に取り扱うCSS

みなさんこんにちは、OneStepです。
今回は珍しくコーディングのTipsを記載してみたいと思います。

CMSなどではコンテンツオーナーがWeb業者ではなくクライアント側になることが多々あるかと思います。
そういう場合、大きさがちぐはぐになってしまうような画像を多数アップされ、不恰好なWebページになってしまうということはありませんか?

そういう場合、状況に応じて一定の間隔を取ったり、体裁を合わせるCSSを記述する必要があります。
ここではその一例を出しておきましょう。

1.以下のようにしたい。

名称未設定-1_01グレーの部分は写真や画像、いわゆるimgタグで表される部分です。
色がついている部分は余白と考えてください。
ただし、コンテンツオーナーがクライアントである以上は、画像が縦長・横長はどちらになるとは言い切れません。
そしてCMSの性質上、画像の枚数は何個でも数が増えることが求められます。

さらに横長の画像は決められた箱に対して上下同じ間隔のマージンを開く必要があります。
また縦長の画像は同じ要領で左右に同じ間隔のマージンが要求されています。

2.求めるべきCSSと問題点

さて、画像の左右のマージンを同じ間隔だけ開くのは有名なCSSがあります。
<p>を画像の前に充てる場合は
——————————————
p { // 該当するimgタグの直前のpタグのこと
text-align: center;
}
——————————————
このようにすれば解決ですね。
また<p>を何らかの理由でつけられない場合は
——————————————
img { // 該当する画像本体
margin: 0 auto;
display: block;
}
——————————————
このようにすれば中央に寄せられます。

そして次に上下を均等にマージンをあける場合です。
——————————————
■HTML
<div class=”img_outer”>
<img src=”images/img01.jpg” alt=”” />
</div>

■CSS
.img_outer {
display: table-cell;
vertical-align: middle;
}
——————————————
このdisplay: table-cellはIE8以降でサポートされているCSSで、該当するクラスを<table>のセルと同じような扱いにするものです。
したがって、vertical-align属性が有効になり、middleで上下の中央寄せができる、というものです。

では、画像の投稿量はクライアント側に委ねられているので、右側に2枚目、3枚目と画像が増えていく、上記の画像のような形にするには…。
——————————————
■HTML
<div class=”img_outer”>
<img src=”images/img01.jpg” alt=”” />
</div>
※以下、CMSの機能により同じHTMLが繰り返され、画像だけ変わる。
<div class=”img_outer”>
<img src=”images/img02.jpg” alt=”” />
</div>
<div class=”img_outer”>
<img src=”images/img03.jpg” alt=”” />
</div>

■CSS
.img_outer {
display: table-cell;
float: left;
vertical-align: middle;
width: 200px;
height: 200px;
margin-right: 20px;
margin-bottom: 20px;
}
.img_outer img {
display: block;
max-width: 200px;
max-height: 200px;
}
——————————————

画像の外側のdivに、上下均等になるようにdisplay: table-cell,vertical-align: middleをかけ、
全体を横並びにするためにfloat:left;をかけています。

ですが、このコーディングは成立しません。

実際に行ってみると、vertical-align: middleがかからない、margin-right: 20px、margin-bottom: 20pxがかからないなどの状況になることが多々あります。おおよそ、こちらが望んだ挙動にはなっていないでしょう。
※ブラウザの解釈やCSSの書き方で症状は異なることがあります。

3.問題解決するには?

さて問題の原因となっているのは、結論から言うとdisplay: table-cellとfloat: left;が共存できないことです。
display: table-cellはあくまでもtableタグの中のセルと同じ挙動にするためのものです。
tableタグの中身……分かりやすく言うと<th>や<td>といったタグが、float: leftやmargin-right: 20pxとCSSを与える人はいないでしょう。

したがって、上記の条件を満たすためには以下のような書き方が必要になります。
structure——————————————
■HTML
<div class=”img_outer”>
<div class=”img_inner”>
<img src=”images/img01.jpg” alt=”” />
</div>
</div>
※以下、CMSの機能により同じHTMLが繰り返され、画像だけ変わる。
<div class=”img_outer”>
<div class=”img_inner”>
<img src=”images/img02.jpg” alt=”” />
</div>
</div>
<div class=”img_outer”>
<div class=”img_inner”>
<img src=”images/img03.jpg” alt=”” />
</div>
</div>

■CSS
.img_outer {
float: left;
width: 200px; // あってもなくてもよいが念のため
height: 200px; // あってもなくてもよいが念のため
margin-right: 20px;
margin-bottom: 20px;
}
img_inner {
display: table-cell;
vertical-align: middle;
width: 200px;
height: 200px;
}
.img_inner img {
display: block;
margin: 0 auto;
max-width: 200px;
max-height: 200px;
}
——————————————

divを二重に記述して、外側のdivにはfloatによって横並びにするCSSを与えます。
そして内側のdivには上下に均等にマージンが割り振られるCSSを与え、
最後に画像本体に左右に均等にマージンが割り振られるCSSを与えていく、という流れです。

4.まとめ

CSSのバッティングを防ぐことを忘れないように、順番にCSSを割り振っていきましょう。

ただし写真を撮影するカメラなどが複数台あり、写真や画像の縦の比率がずれる場合があります。
こういう場合は時には、縦のセンタリングをしないほうがいい場合もあります。
(画像の頭の部分を合わせて綺麗に表示させる、という意味です)

クライアント側にコンテンツを引き渡す場合は、こういったカメラの様相などもチェックするようにしておくとよいでしょう。ディレクターやプロデューサーの方と連携してクライアントの様子を掴み、コーディングすることが望ましいと言えますね。