グリッドレイアウトで高さも横幅もバラバラの画像を綺麗に並べる方法

珍しくデザインに関するお話です。弊サイトでは、WordPressのテーマを独自作成し、テーマの構築にCSSフレームワークであるTwitter Bootstrapを使用しています。Bootstrapを使用することで、車輪の再発明を行うことなく、誰もが簡単にレスポンシブデザインに対応したテーマを作成できます。

デバイスの横幅(width)に応じて、コンテンツの内容(グリッドの数)が動的に変化するのも、メディアクエリ(media query)と呼ばれるCSSをBootstrapが使用しているからですね。

弊サイトでは、デスクトップやラップトップのブラウザで閲覧すると、このように2列のレイアウト(グリッドレイアウト)表示となりますが、スマートフォンなど横幅が小さなデバイスになると、視認性を考慮して1列になるようにしています。これもBootstrapを使用すると容易に実現できます。

ただし、このグリッドレイアウトにおいて1点問題がありました。それは、過去の自分の怠慢から、アイキャッチ画像の横幅や高さがバラバラであったということです。このように横幅や高さの異なるアイキャッチ画像をそのままグリッドレイアウトで表示するとこのようになります。

See the Pen oYWyqo by ottan (@ottanxyz) on CodePen.

高さがバラバラであるため、まったくもって統一性がありませんね。横幅については、max-width: 100%;で、親要素(グリッド)の最大幅を超えて表示しないように調節しています。この指定がないと、綺麗に整えられたグリッドの幅を超えて、画像がはみ出して表示されてしまいます。では、幅は揃えられたとして、高さはどのように揃えるのが良いのでしょうか。ここでは一例をご紹介します。

CSSのみで高さも横幅もバラバラの画像をぴったりに並べる

先ほどの高さがバラバラだったイメージを綺麗に並べた完成形がこちらです。あくまで一例ですが、もっとも容易に綺麗に高さを揃えることのできる素晴らしい方法だと思います。CSSに詳しい方にとっては何てことのない方法だと思いますが、私はデザイナーではないので苦労しました。

See the Pen ZBKRoQ by ottan (@ottanxyz) on CodePen.

ポイントは、overflow: hidden;です。親要素(グリッド)のボックスに入りきらない子要素(イメージ)を隠してしまうというものです。また、親要素(グリッド)にposition: relative;、子要素(イメージ)にposition: relative;を指定することで、親要素(グリッド)の左上を基準として、子要素(イメージ)の表示位置を指定します。

img {
  max-width: 100%;
}

.grid-img {
  position: relative;
  overflow: hidden;
}

.grid-img img {
  position: absolute;
}

親要素(グリッド)の高さの最小値は1pxであるため、このままでは画面に何も表示されません。そこで、画面に表示する画像の高さを指定します。この際に、絶対値指定(たとえば、100pxなど)としてしまうと、デスクトップでもスマートフォンでも、グリッドの幅がデバイスの幅に応じて変化しても、指定した高さの画像が表示されてしまうため、相対指定とします。また、子要素であるimgタグに高さを指定しても、親要素のoverflow: hidden;によって隠されてしまうため、親要素に指定する必要があることに注意してください。

では、子要素(イメージ)の高さが不明な場合、親要素(グリッド)の高さはどのように指定するのが良いでしょうか。ここでちょっとしたトリックを使用します。padding-bottom: 30%;、もしくはpadding-top: 30%;と指定してみてください。これで、子要素(イメージ)の比率は保ったまま画像を崩さず、親要素の幅に応じて高さが可変となる魔法のレイアウトの完成です。

img {
  max-width: 100%;
}

.grid-img {
  position: relative;
  overflow: hidden;
  padding-bottom: 30%;
}

.grid-img img {
  position: absolute;
}

padding-bottom: 30%;は、親要素(グリッド)の高さを指定するものではありません。あくまで、親要素(グリッド)のボックスに子要素であるイメージを表示する際に、親要素のボックスの下側に空白を表示するというものです。その空白を利用して画像を表示しているのです。

img {
  max-width: 100%;
}

.grid-img {
  position: relative;
  overflow: hidden;
  padding-bottom: 30%;
}

.grid-img img {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}

このままでは画像の表示位置がバラバラです。さらに、子要素(イメージ)に対して表示位置をすべて0指定とした上で、margin: auto;として指定することで、画像の真ん中の部分をトリミングしたような形で綺麗に高さが揃えられて表示されるようになります。

参考リンク

下記のサイトが大変参考になりました。padding-bottom、もしくはpadding-topに指定する値は、下記のサイトの通り、子要素のアスペクト比(すなわち、高さ÷横幅の比率)を指定することで、その比率を保ったまま高さが可変となる要素を作ることができます。(レスポンシブなYouTubeのiframe対応など)難しいですが、おもしろいですね!

https://design-spice.com/2014/03/24/percentag/

comments powered by Disqus