縦横比固定画像ボックス CSS(レスポンシブ対応)

# レスポンシブ対応画像ボックス縦横比固定CSS

必要になったので、テストを兼ねて作ってみました。

仕様

- レスポンシブ
- 固定ボックス(親)内に画像(子)が入るデザイン
- 親ボックス縦横比を維持したまま画面サイズに応じて拡大縮小
- どんなアスペクト比の画像でも対応
- 画像の長辺最大サイズが親ボックス内に収まり、かつ縦横中央揃え、画像オリジナルサイズ以上の拡大はしない
- flexboxカラムレイアウトに対応
- 対象ブラウザ(一部未検証)：chrome/firefox最新、IE11 Edge、android4.4～、ios9～

## html

実際のデザイン内での実装を想定したコードですので、画像ボックス以外の要素も含んでいます。

```
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css">
<!--<script src="https://code.jquery.com/jquery-3.2.1.js"></script> ※使いません-->
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="l-contents-body">
  <h1>aspect-ratio-box</h1>

  <p>sample aspect ratio 4:3</p>

  <div class="sample">
    <div class="c-image-panel">
      <div class="inner"><img src="https://placehold.jp/640x360.png"></div>
    </div>
    <p>foo bar baz qux. hoge fuga piyo.</p>
  </div>

  <p>2 Columns Layout with Flexbox</p>

  <div class="l-flex-row">
    <div class="l-flex-col sample">
      <div class="c-image-panel">
        <div class="inner"><img src="https://placehold.jp/640x360.png"></div>
      </div>
      <p>foo bar baz qux. hoge fuga piyo.</p>
    </div>
    <div class="l-flex-col sample">
      <div class="c-image-panel">
        <div class="inner"><img src="https://placehold.jp/480x640.png"></div>
      </div>
      <p>foo bar baz qux. hoge fuga piyo.foo bar baz qux. hoge fuga piyo.</p>
    </div>
  </div>

  <p>3 Columns Layout with Flexbox</p>

  <div class="l-flex-row">
    <div class="l-flex-col sample">
      <div class="c-image-panel">
        <div class="inner"><img src="https://placehold.jp/640x360.png"></div>
      </div>
      <p>foo bar baz qux. hoge fuga piyo.</p>
    </div>

    <div class="l-flex-col sample">
      <div class="c-image-panel">
        <div class="inner"><img src="https://placehold.jp/480x640.png"></div>
      </div>
      <p>foo bar baz qux. hoge fuga piyo.foo bar baz qux. hoge fuga piyo.</p>
    </div>
    <div class="l-flex-col sample">
      <div class="c-image-panel">
        <div class="inner"><img src="https://placehold.jp/640x480.png"></div>
      </div>
      <p>foo bar baz qux. hoge fuga piyo.</p>
    </div>
  </div>

</div>
</body>
</html>
```

## CSS(sass)


```
@charset "utf-8";
//* normalize */
// https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css

/* sample initialize */
*, *::before, *::after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

img {
  width: 100%;
  height: auto;
  vertical-align: bottom;
}

/* sample style */
.l-contents-body {
  margin: 12px;
}

.l-flex-row {
  display: -webkit-box;
  display: flex;
  -ms-flex-wrap: nowrap;
  flex-wrap: nowrap;
  -webkit-justify-content: space-between;
  justify-content: space-between;
}
.l-flex-col {
  -webkit-flex-grow:1;
  flex-grow: 1;
  &:not(:first-child){
    margin-left: 12px;
  }
}

.sample {
  width: 100%;
  padding: 10px;
  border: 1px solid #999;
  background-color: #eee;
}

/* component style */
.c-image-panel {
  position: relative;
  width: 100%;
  &::before {
    display: block;
    padding-top: 75%; // aspect ratio 4:3 ※横幅に対する縦比率を%で設定
    background-color: #000;
    content: '';
  }
  .inner {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
  }
  img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    
    // 画像縦横中央揃え用
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate3d(-50%, -50%, 0);
    transform: translate3d(-50%, -50%, 0);
  }
//  画像縦横中央揃え flexbox版 IE11で画像の縦横非が崩れるバグ有(img要素をflex-itemにすると発生)
//  .inner {
//    position: absolute;
//    top: 0;
//    right: 0;
//    bottom: 0;
//    left: 0;
//    display: -webkit-box;
//    display: flex;
//    -webkit-justify-content: center;
//    justify-content: center;
//    -webkit-align-items: center;
//    align-items: center;
//    text-align: center;
//    vertical-align: middle;
//  }
//  img {
//    width: auto;
//    height: auto;
//    max-width: 100%;
//    max-height: 100%;
//  }
}
```

## 参考

- [CSSだけでアスペクト比を固定するテク](http://qiita.com/ryounagaoka/items/a98f59347ed758743b8d)
- [レスポンシブWebデザインでハマりがちな%指定](http://design-spice.com/2014/03/24/percentag/)
- [【CSS】画像の上下中央配置とか画像配置に関するいろいろ](https://blog.mismithportfolio.com/web/20151027cssimageplace)
- [flexboxのバグに立ち向かう（flexboxバグまとめ）](http://qiita.com/hashrock/items/189db03021b0f565ae27)

ありがとうございました。