各ブラウザ対応!アスペクト比を保ったまま要素を幅可変に対応させる方法

Pocket
LINEで送る

レスポンシブ対応、もっと言えば各ブラウザ・ブラウザ幅でも表示崩れを起こさないのが常識とされるようになったコーディング作業。
各要素も当然アスペクト比を保って縦横比を崩さず表示させたい!
うろ覚えのまま毎回調べてるから、記事としてアウトプットすることでちゃんと理解しようと思います。

2020.06.05. Bootstrapでの場合も追記しました。

1: imgタグで画像ベタ貼り編

これは簡単というかそのままなんですけど、基本 is 大事。

img {
 width: 100%;
 height: auto;
}

2: iframeで動画を埋め込む編

iframeはwidthやheightにautoを指定することができないので、1: imgタグで画像ベタ貼り編のやり方はできません。
そこで、iframe自体でアスペクト比を保った高さを指定するのではなく、iframeを包む親要素を作成し、さらのその擬似要素padding-topでアスペクト比から割り出した%を指定することによって高さを設定します。

参考:そもそもpadding-topの%って何? どこ基準?

下記サイトの記事できれいにまとめられているので参照なさってください。


padding、そしてmarginもパーセント指定した場合は、親要素の幅を基準にするんですね。
そのため、親要素にpaddog-topで高さ指定するのではなく、擬似要素の方にpaddog-topを%指定して、横幅の比率を保った高さにします。

padding-topのアスペクト比指定ですが、%ではなくcalc()でも指定できます。
むしろそっちの方がスマートなのですが、IE11で例えばwidth: calc(100% / 3);などの場合に表示崩れが起きてしまいます。ハックを使うか、%指定で表記を統一するか、チームのやり方にしたがいましょう。

Youtube動画を配置

例として友達が歌を担当しているYoutube動画を配置してみます。
埋め込みたい動画の共有から埋め込むで埋め込みコードを取得します。
iframeタグ内にwidthとheightの指定が入っていますが、そのままでも削除しちゃってもOKです。ここではシンプルなコードにしたいので削除しました。

<div class="iframe_wrapper">
  <iframe src="https://www.youtube.com/embed/Un05KNjlUaQ" frameborder="0" allow="accelerometer; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>

Youtube動画のアスペクト比は16:9なので、高さは横幅の56.25%となります。この56.25%を親要素の擬似要素にpadding-topで指定します。

埋め込むiframeの幅、高さはどちらも100%を指定します。
position: absolute; width: 100%; height: 100%; top: 0; left: 0;なので、親要素のサイズぴったりになります。

div.iframe_wrapper {
    position: relative;
    width: 100%; /* ここは適時編集してください(px指定してmin-widthと組み合わせるなり) */
}
div.iframe_wrapper::before {
    content:'';
    display: block;
    padding-top: 56.25%; /* 高さ÷横幅×100 */
}
div.iframe_wrapper iframe {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
}

埋め込み結果: 埋め込みコードそのまま編

iframeの高さが固定のためブラウザ幅が小さくなった場合、はみ出してしまいます。

埋め込み結果: 埋め込みコードのwidthを100%に、heightをautoにしてみた編

幅は100%になったのですが、高さ指定がおかしくなってしまいました。
(ちなみに、heightも100%にしてみた場合、chromeではautoの場合と変化ありませんでした)

埋め込み結果: 親要素で囲んでアスペクト比固定した編

ブラウザ幅を狭めてみてください。横幅に合わせて高さも比率が崩れることなく可変してくれます。

3: ブロックレベル要素編

使用頻度が高いのはこのパターンだと思います。
2: iframeで動画を埋め込む編の応用になりますが、こちらはアスペクト比を設定したい要素にheight: 100%;を指定して親要素のサイズに合わせるのではなく、 position: absolute; top: 0; left: 0; bottom: 0; right: 0;を指定して親要素のサイズの位置に引き伸ばす設定をします(ニュアンス分かりますでしょうか……)。

<div class="testBlock_wrapper">
 <div class="testBlock">幅の50%の高さです。</div>
</div>
div.testBlock_wrapper {
    position: relative;
    width: 100%; /* ここは適時編集してください(px指定してmin-widthと組み合わせるなり) */
}
div.testBlock_wrapper:before {
    content:'';
    display: block;
    padding-top: 50%; /* 高さ÷横幅×100 */
}
div.testBlock_wrapper div.testBlock {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background: #b9b2a2; /* 表示確認用 */
}

配置結果

ここでは幅:高さ=2:1→padding-top:50%;で指定しました。ブラウザ幅を狭めてみてください。

幅の50%の高さです。

padding-topとパーセンテージ指定については、前述2: iframeで動画を埋め込む編内の「参考:そもそもpadding-topの%って何? どこ基準?」で触れています。

Bootstrap4.0での場合

Bootstrapなら要素にclassを指定すれば反映されます。
親要素にembed-responsiveとアスペクト比を指定するclassを付加し、子要素のiframeにembed-responsive-itemを付加します。

アスペクト比 class
21:9 embed-responsive-21by9
16:9 embed-responsive-16by9
4:3 embed-responsive-4by3
1:1 embed-responsive-1by1

Bootstrap、便利ですね〜〜〜。
Youtube動画は16:9なので、親要素にembed-responsiveembed-responsive-16by9を付加します。

<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/Un05KNjlUaQ" allowfullscreen=""></iframe>
</div>
Pocket
LINEで送る

back to top