アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

画像付きリストのテキストを縦方向に中央揃えする(リキッドレイアウト対応)

こんにちは、鴨田です。

何らかの要素が縦横中央揃えになっているデザインが結構な頻度で出てきます。
デザイナーとしては見栄えを考えてそうしているのですが、
コーダーとしては、横方向はまだしも縦方向の中央揃えは何かと面倒だったりします。

いくつかケースがあると思うので、それぞれに関して自分ならこうする、
というコーディングをしていきたいと思います。

とある要素の中で画像だけを縦横中央揃えしたい、というケースもあると思いますが、
今回は画像があってその横に来るテキストを縦方向に中央揃えしなければならない、
というデザインに特化した説明をします。

また、画像の横幅は決まっているけど、テキスト部分の横幅が可変となっていて、
かつ、画像とテキストを内包するリンクは縦横いっぱいにリンクエリアが確保されている
というリキッドレイアウトとします。



0.元となるHTML



HTML


<div class="wrap">
  <a href="#">
    <div><a href="https://www.asial.co.jp100-100.png &mode=1" class="popupimg"><img src="https://www.asial.co.jp100-100.png"></a></div>
    <p>画像アリ一行テキスト</p>
  </a>
  <a href="#">
    <p>画像ナシ一行テキスト</p>
  </a>
  <a href="#">
    <div><a href="https://www.asial.co.jp100-100.png &mode=1" class="popupimg"><img src="https://www.asial.co.jp100-100.png"></a></div>
    <p>画像アリ複数行テキスト画像アリ複数行テキスト画像アリ複数行テキスト</p>
  </a>
  <a href="#">
    <p>画像ナシ複数行テキスト画像ナシ複数行テキスト画像ナシ複数行テキスト</p>
  </a>
</div>


<img>を<div>で囲んでいますが、場合によっては囲う必要はありません。
(1と3のケースでは、囲う必要はありません。
 divに指定しているCSSをimgに適用すれば動くはずです)

これから各ケースにおいて、CSSの説明をしますが、
デザイン上の装飾に関しては、スルーします。
縦方向の中央揃え、リキッドレイアウトに関する箇所のみの説明となります。



1.line-heightを使う



CSS


.wrap {
  border-top: 1px solid #666;
}

.wrap a {
  width: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  text-decoration: none;
  color: #333;
  background: #eee;
  border-bottom: 1px solid #666;
  display: block;
}

.wrap a:hover {
  background: #eff;
}

.wrap div {
  display: inline-block;
  margin: 0 5px 0 0;
  vertical-align: middle;
}

.wrap p {
  display: inline-block;
  line-height: 100px;
}



デモページ

<img>を含む<div>に対して、"vertival-align"を指定し、
横に並ぶ<p>に"line-height"を画像の高さに合わせて指定することで、
縦方向に中央揃えとすることが出来ます。

テキストが絶対に一行に収まるときは、この方法が一番楽な実装になると思いますが、
テキストが複数行になると派手に崩れます。



2.display: table-cellを使う



CSS


.wrap {
  border-top: 1px solid #666;
}

.wrap a {
  width: 100%;
  height: 120px;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  text-decoration: none;
  color: #333;
  background: #eee;
  border-bottom: 1px solid #666;
  display: table;
}

.wrap a:hover {
  background: #eff;
}

.wrap div {
  display: table-cell;
  width: 100px;
  padding: 0 5px 0 0;
}

.wrap p {
  display: table-cell;
  vertical-align: middle;
  line-height: 1.2;
}



デモページ

まず、<div>と<p>を内包する<a>に、"display: table"を指定し、
<div>と<p>に"display: table"を指定することで、横並びのリキッドレイアウトを実現します。

<div>に"width"をpx指定することで、<p>の幅は可変となります。
最後に、<p>に"vertical-align"を指定することで、縦方向に中央揃えとなります。



3.box-align: centerを使う



CSS


.wrap {
  border-top: 1px solid #666;
}

.wrap a {
  width: 100%;
  height: 120px;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  text-decoration: none;
  color: #333;
  background: #eee;
  border-bottom: 1px solid #666;
  display: -webkit-box;
  display: -moz-box;
  display: -o-box;
  display: box;
  -webkit-box-align: center;
  -moz-box-align: center;
  -o-box-align: center;
  box-align: center;
}

.wrap a:hover {
  background: #eff;
}

.wrap div {
  width: 100px;
  padding: 0 5px 0 0;
}

.wrap p {
  -webkit-box-flex: 1.0;
  -moz-box-flex: 1.0;
  -o-box-flex: 1.0;
  -ms-box-flex: 1.0;
  line-height: 1.2;
}



デモページ

<div>と<p>を内包する<a>に、"display: box"を指定することで、自身をボックス要素とし、
さらに、"box-align: center"を指定することで、子要素の縦方向の揃え位置が中央揃えになります。

<div>に"width"をpx指定し、<p>には"box-flex"を指定することで、
横並びのリキッドレイアウトとなります。



以上です。

IE9での対応を考えると、2の方法がオススメですが、
古いIEまで考えると、実は2も3も使えなかったりします。
その時は真面目にmarginを使用して、行数に応じたクラスを作成するなどして、
どうにかするしかありません。

スマホ対応やモダンブラウザだけでいいのであれば、
是非試してもらえたらと思います。