Open1

Aspect ratio boxの翻訳メモ

Aspect Ratio Boxes

The Core Concept: padding in percentages is based on width

縦方向のパディングのように、それが少し直感的でない場合でも、ここで紹介する方法は有効なものです。

padding-toppadding-bottomは親要素のwidthに基づいています。

つまり、widthが500pxの要素があり、padding-topが100%だった場合、padding-topは500pxになります。

これは、500px×500pxの完全な正方形にはなりませんか。理由はアスペクト比です。

ここで要素の高さを強制的に0にして(height: 0;)、ボーダーをつけないようにします。すると、パディングがボックスモデルの高さに影響を与える唯一の要素となり、正方形ができあがります。

ここで、上部のパディングを100%ではなく、56.25%にしたとします。56.25というのは16:9の比率に等しいです。(9/16 = 0.5625).

これでアスペクト比が1:1のボックスができました。widthが動的な環境でもうまく機能します。widthが変更されると、heightも変更され、要素はアスペクト比を維持してくれます。

参考動画: https://css-tricks.com/videos/aspect-ratio-box.mov

Use case: a background-image

タイポグラフィのロックアップを作りたいとしましょう。これは記事のタイトル用なので、<h1>タグを使うのは理にかなっています。

<h1>
  Happy Birthday
</h1>

その<h1>タグをアスペクト比が一定なボックスにして、ロックアップを背景画像として適用することができます。

h1 {
  overflow: hidden;
  height: 0;
  padding-top: 56.25%;
  background: url(/images/happy-birthday.svg);
}

参考動画: https://css-tricks.com/videos/lockup-resize.mov

しかし、上のアスペクト比については嘘をつきました。これは実際にはアスペクト比が16:9の画像ではありません。この画像はストックフォトのサイトからダウンロードしたものです。

たまたまSVGで、viewBox="0 0 1127.34 591.44"となっているので、アスペクト比的には1127.34×591.44の画像になります。あるいは、328×791の画像になっていたかもしれません。

ランダムな画像が、あらかじめ定義された特定のアスペクト比に収まらないことはよくあることだと思いますが...。

The Math of Any Possible Aspect Ratio

完全な正方形や16:9のアスペクト比は素晴らしいものですが、それらに使われている値は単純な計算に過ぎません。

アスペクト比は状況によってさまざまな値をとりえます。ビデオや画像はどんなサイズにでも切り取ることができます。

では、上の1127.34×591.44のSVGのpadding-topはどのようにして求めるのでしょうか?

calc()を使えば次のように求められます。

    padding-top: calc(591.44 / 1127.34 * 100%);

sassの場合は次のようにかけます

    padding-top: 591.44px / 1127.34px * 100%;

How do you put content inside if padding is pushing everything down?

上の背景画像のサンプルでは、コンテンツ(Happy Birthdayという文章)をpadding-topで下に押し出させ、オーバーフローを隠すことで、コンテンツを隠しました。

h1 {
  overflow: hidden;
  height: 0;
  padding-top: 56.25%;
  background: url(/images/happy-birthday.svg);
}

しかし、コンテンツを中に入れたまま、つまりコンテンツを隠さずにアスペクト比が一定のボックスが必要な場合はどうでしょうか?

これは少し厄介です。下に押し出したコンテンツを元の位置に戻す必要があります。そのためには、絶対配置が有効です。

例えば、今回のようなコンテンツとしてテキストだけを使っていて、アスペクト比が一定のボックスが必要だとします。

絶対配置のためには、内部にラッパーが必要です。クラス名を具体的に説明しましょう。

<h1 class="aspect-ratio-box">
  <div class="aspect-ratio-box-inside">
    Happy Birthday
  </div>
</h1>

これに以下のcssをかけて配置を調整します。

.aspect-ratio-box {
  height: 0;
  overflow: hidden;
  padding-top: 591.44px / 1127.34px * 100%;
  background: white;
  position: relative;
}
.aspect-ratio-box-inside {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

試しに、テキストを中央揃えにして、ボックスに合わせてサイズを調整してみましょう。

<h1 class="aspect-ratio-box">
  <div class="aspect-ratio-box-inside">
    <div class="flexbox-centering">
      <div class="viewport-sizing">
          Happy Birthday
      </div>
    </div>
  </div>
</h1>

cssには以下を付け加えます。

.flexbox-centering {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.viewport-sizing {
  font-size: 5vw;
}

参考動画: https://css-tricks.com/videos/aspect-ratio-text.mov

References

ログインするとコメントできます