[CSS]YouTubeなどの動画をレスポンシブ対応で実装する現在主流とこれからのテクニック
Post on:2017年5月19日
動画は拡大縮小が簡単な画像とは異なり、アスペクト比を維持したままレスポンシブ対応で埋め込むと、幅のサイズだけが変わり、高さがそのままになってしまいます。
この問題を解決するには、動画を配置するiframeをdivなどの親コンテナで内包し、アスペクト比にあった高さをpaddingで指定し、親コンテナのサイズに合わせて動画のサイズを変更させます。
動画をレスポンシブ対応で実装する現在主流となっているテクニックの解説と、もっとスマートに実装できるこれからのテクニックを紹介します。
Experiments in fixed aspect ratios
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
動画をレスポンシブ対応で、アスペクト比を維持したまま配置
これを実現するためのテクニックはいくつかのバリエーションがありますが、それらすべての共通点はpaddingを使用して、あらかじめアスペクト比を指定した親コンテナを作成しておく必要があります。
まずは、そのpaddingを使った実装を見てみましょう。
heightではなく、paddingで高さを指定するというのは、生成されたボックスの包含ブロックの高さに対してパーセントで算出される高さとは異なり、包含ブロックの幅を参照するということです。これで、高さを幅に対して相対的にすることができます。
これを利用して、heightに0、padding-topに「height/width*100%」を指定することで、適切なアスペクト比のコンテナ要素を実現できます。アスペクト比が16:9(YouTubeの標準縦横比)のコンテナの場合、マークアップは次のようになります。
1 2 3 |
<div class="container"> <iframe class="embed"></iframe> </div> |
親コンテナのCSSは次のようになります。
「56.25%」は、アスペクト比16:9を元に算出します。
1 2 3 4 5 6 |
.container { position: relative; width: 100%; height: 0; padding-top: 56.25% // =9/16*100% } |
動画を埋め込むifarmeは絶対配置にし、サイズには100%を指定します。
1 2 3 4 5 6 7 |
.embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } |
ビューポートのサイズに応じて拡大縮小するため、動画は常にそのコンテナで定義された適切な縦横比を維持します。実際の動作は、デモページでご覧ください。
See the Pen Fixed aspect ratio video embeds - padding trick by Stephanie (@ramenhog) on CodePen.
このテクニックのバリエーションとしてコンテナ要素に擬似要素を定義し、コンテナ要素の代わりにアスペクト比を指定することができます。
1 2 3 4 5 6 7 8 9 10 11 |
.container { position: relative; width: 75%; &:before { content: ""; display: block; width: 100%; padding-top: 56.25%; } } |
このバリエーションは動画がブロックを含む100%の幅になることを望まない場合に役立ちます。疑似要素にアスペクト比を指定することで、コンテナの幅が変更されたときにpadding-topのパーセントが再計算されることを心配する必要はありません。しかし、コンテナに「display: flex;」がある場合、この擬似要素のテクニックはFirefoxでうまく機能しません。
そこで、CSS Grid Layoutだとうまくいくのではないか、と考えました。
CSS Grid Layoutの素晴らしい点の1つは、グリッドの子要素を2次元でコントロールできることです。これは、アスペクト比を制御するために必要な要素です。
もっとスマートに実装するためのスタディ
私が取ったアプローチは、アスペクト比の幅数で定義されたコンテナグリッドを作成することでした。
最初のデモではアスペクト比16:9だったので、グリッドコンテナにも16個のカラムを定義します。
これらのカラム幅にvw単位を使用し、各カラムをビューポート幅の割合から定義し、ビューポート幅によってカラム全体を調整できるようにします。カラムのサイズを取得するために、ビューポートをカラム数で割り、vwのカラムの実際のサイズを取得するようにコンテナを取り出します。
グリッドの横行を縦列と同じサイズに設定し、各グリッドのセルをアスペクト比1:1の正方形にします。暗黙的に横行の数を設定するのではなく、grid-auto-rowsで必要に応じてサイズを設定した新しい横行を自動的に作成します。
1 2 3 4 5 |
.container { display: grid; grid-template-columns: repeat(16, 5.625vw); grid-auto-rows: 5.625vw; } |
動画を配置する.embedには、アスペクト比を元に、グリッドセルの数を水平と垂直方向に定義します。また、iframeにはheightプロパティとwidthプロパティを定義する必要があるため、100%に設定します。
1 2 3 4 5 6 |
.embed { grid-column: span 16; grid-row: span 9; width: 100%; height: 100%; } |
私はこのアプローチが非常に直観的で、好きになりました。
アスペクト比を親コンテナに定義するのではなく、動画に定義するからです。
See the Pen CSS Grid Experiment: fixed aspect ratio video embed by Stephanie (@ramenhog) on CodePen.
このアプローチでもっとも楽しい部分は、グリッドセルのサイズ計算です。レスポンシブ対応で1:1のグリッドセルを作成するには、ビューポートの幅に基づいてサイズを設定する必要があるため、動画がネストされていると計算は非常に面倒です。
もし別のブレークポイントでコンテナの全体の幅を変更したい場合は、セルサイズを再計算する必要があります。その時は、CSSのカスタムプロパティを使用して、別のブレークポイントで--cellSizeプロパティに新しい値を設定するだけです。私はそのカスタムプロパティを使用して、グリッドの列と行のサイズを設定しました。
また、動画のサイズを最大限にするには、セルサイズを特定のブレークポイントで固定のピクセル値に設定する必要があります。これは頭痛の種にもなりがちです。
それでも、このような古い問題を時代遅れにする新しいアプローチを与えてくれたCSS Grid Layoutに感謝を伝えたいです。
動画自体にアスペクト比を定義することは、CSSがどのように機能するか直感的に分かる記述です。CSS Grid Layoutのアスペクト比に期待しているのは、私だけではないように思います。
CSS Grid Layoutをサポートするブラウザは、IEを含め最新のバージョンに限られるため、旧バージョンをサポートする場合には注意が必要です。しかし、このアスペクト比を使ったテクニックはCSSの開発をよりエキサイティングにするでしょう。
sponsors