CSS・画像の縦横比を維持してレスポンシブデザイン

サイトをレスポンシブでデザインする際、画像をいくつか並べて、その縦横比を維持しながら、どんな画面サイズでも指定の横幅いっぱいに美しく並べる方法です。


こういうことです。

f:id:ausnichts:20190917184029j:plain

サイト:そんなには褒めないよ。映画評




画像が background の場合

カラム数については後回しにして、まずはひとつずつの画像を一定の比率のまま拡大縮小する方法です。


はてなブログを例に取りますと、トップページの表示形式を一覧表示にした場合、各記事のアイキャッチ画像は次のように background-image となっています。

<a href="https://www.movieimpressions.com/entry/onceinhollywood" class="entry-thumb-link">
  <div class="entry-thumb" style="background-image: url('https://cdn.image.st-hatena.com/image/square/ed05e0b9e17714d710d3d4ffed4f7b187e614285/backend=imagemagick;height=500;quality=80;version=1;width=500/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fausnichts%2F20190916%2F20190916105350.jpg');">
  </div>
</a>


このままですと画像が 500px四方にトリミングされていますので、まずは画像をオリジナルのものに差し替えます。差し替える方法は次の記事にあります。


オリジナル画像に差し替えられ、こうなります。

<a href="https://www.movieimpressions.com/entry/onceinhollywood" class="entry-thumb-link">
  <div class="entry-thumb" style="background-image: url(&quot;https://cdn-ak.f.st-hatena.com/images/fotolife/a/ausnichts/20190916/20190916105350.jpg&quot;);">
  </div>
</a>


このHTMLに次のCSSをあてますと画像サイズを変更しても縦横比が維持されたままになります。

.page-index .entry-thumb-link {
    display: block;
    position: relative;
    width: 100%;
    padding-top: 56.25%;
}
.page-index .entry-thumb-link .entry-thumb {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-size: cover;
    /* 以下は上位で指定されたスタイルを解除のため */
    float: none;
    margin: 0;
}


肝は padding-top: 56.25%; で横幅に対して縦を 56.25% にするということです。なぜ padding-top を使うかといいますと、縦横比を維持するためには横幅に対する縦幅を指定する必要がありますが、height をパーセントで指定しても縦幅に対する比率ですので縦横比は維持できません。ですのでコンテナの width に対する比率となる padding を使います。

こうしておけば、横幅が伸縮しても縦幅は必ず一定比率になります。56.25%は 16:9 の場合で、4:3 にする場合は 75%を指定します。

あとは、そのコンテナの中に画像を background-size: cover; でいっぱいに表示するだけです。


画像が img タグの場合

画像が background-image としてではなく imgタグで表示されている場合はどうすればいいのでしょう。


はてなブログの場合、サイドバーのモジュールの画像は次のように imgタグで表示されます。この画像も 500px四方にトリミングされていますので同じようにオリジナルに差し替えてあります。

<a class="urllist-image-link recent-entries-image-link" href="https://www.movieimpressions.com/entry/onceinhollywood">
  <img alt="" src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/ausnichts/20190916/20190916105350.jpg" class="urllist-image recent-entries-image" title="" width="100">
</a>


この場合でもほぼ同じように縦横比を維持することができます。

.urllist-image-link {
    display: block;
    width: 100%;
    position: relative;
    padding-top: 56.25%;
    overflow: hidden;
}
.urllist-image {
    width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* 以下は上位で指定されたスタイルを解除のため */
    float: none;
    margin: 0;
}


こちらの肝は、コンテナに overflow: hidden; を指定してはみ出し分を非表示にしていることと、画像をコンテナの中央に配置するために transform: translate(-50%, -50%); を使っている点です。ただし、この方法は横幅優先ですので、指定比率からはみ出した縦部分は上下でカットされます。


object-fit を使う方法

画像の配置に object-fit を使う方法もあります。ただし、IEは対応していません。

object-fit - CSS: カスケーディングスタイルシート | MDN


.urllist-image {
    width: 100%;
    position: absolute;
    top: 0;
    object-fit: cover;
    float: none;
    margin: 0;
}


Grid Layout

複数カラムのデザインをする場合、各カラムのマージンも含め、一定比率で指定横幅いっぱいに表示しつつレスポンシブデザインにするには、Grid Layout がベストではないかと思います。

この件、過去にいろいろやってみた結果が次の記事にあります。

www.imuza.com


半年ほど前の記事ですので、再度いろいろ試して記事としてまとめようと思っています。