YoutubeやInstagramはiframeを用いてブログなどに動画を埋め込みます。
しかし、ただサービスが発行する埋め込みタグを使用しただけでは、レスポンシブにはならず、画面の幅を狭くしたり、幅の狭い端末で表示させたりすると、動画が枠外にはみ出してしまいます。
こんな感じに。
それを解消する手段として、以前以下のような記事を書きました。
これらの方法は、iframeをレスポンシブ表示用のdivラッパーでくるみ、スタイルを調整することで動画をレスポンシブ表示させていました。
しかし、これらの方法は、iframe全てにレスポンシブ表示用のdivラッパーで囲んでしまうので、関係のないiframeまでレスポンシブ表示させてしまっていました。(例えばアマゾンアソシエイトデフォルトの個別商品リンクなどまでレスポンシブ表示されていた。)
これだと、やはり都合が悪いので、「特定のレスポンシブ表示が必要なサービスにだけ処理を施す」ということがしたいです。
ということで今回の場合だと、YoutubeやInstagramの埋め込みタグの時だけレスポンシブ表示用のdivラッパーで囲むということを行いたいと思います。
photo by jonsson
目次
特定サービスの埋め込みiframeだけレスポンシブ化する方法
今回は、Wordpressのfunctions.phpで、PHP&正規表現だけを用いてサーバー処理だけで実装したいと思います。
以前書いたInstagramのiframeをレスポンシブ対応にする方法と違って、JavaScriptでクラスの付け替えなどをする必要がないので、やり方としては幾分スマートになったかと思います。
以下は、コピペのみで行います。このような処理が必要になった場合は、手軽に試してみてください。
functions.phpの編集
functions.phpに以下を追記します。
//iframeのレスポンシブ対応 function wrap_iframe_in_div($the_content) { if ( is_singular() ) { //YouTube動画にラッパーを装着 $the_content = preg_replace('/<iframe[^>]+?youtube\.com[^<]+?<\/iframe>/is', '<div class="video-container"><div class="video">${0}</div></div>', $the_content); //Instagram動画にラッパーを装着 $the_content = preg_replace('/<iframe[^>]+?instagram\.com[^<]+?<\/iframe>/is', '<div class="instagram-container"><div class="instagram">${0}</div></div>', $the_content); } return $the_content; } add_filter('the_content','wrap_iframe_in_div');
これは、Wordpressの本文表示をフックして本文中内のiframeに処理を施す関数です。
PHPの正規表現置換関数preg_replace()を用いて、特定のiframe部分のみを置換します。
YouTubeの時は、
/<iframe[^>]+?youtube\.com[^<]+?<\/iframe>/is
Instagramの時は、
/<iframe[^>]+?instagram\.com[^<]+?<\/iframe>/is
という正規表現を用いて、iframeのsrcに含まれるサービスのドメイン名でレスポンシブ表示用のdivラッパーを装着するか判別します。
YouTubeの場合は、「youtube.com」が含まれているとき、Instagramの場合は「instagram.com」が含まれているとラッパーを装着します。それ以外の場合は、iframeにラッパーが装着されないので、通常通り表示されます。
もし、新たなサービスを加えたければ、
$the_content = preg_replace(サービスごとの引数);
と追記していくだけです。
新たな正規表現を作成する場合は、以下のサービスを使用すると、トライ&エラーを手軽に何度も行うことができて便利です。
style.cssの編集
YouTubeなどのiframe動画をレスポンシブ表示するときの、スタイルは以下のようになります。
/************************************ ** video ************************************/ /*動画の最大幅を指定する*/ .video-container, .instagram-container{ max-width:640px; } /*動画の大きさを調整*/ .video { position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden; max-width: 100%; height: auto; } /*Instagramの大きさを調整*/ .instagram { position: relative; padding-bottom: 120%; padding-top: 30px; height: 0; overflow: hidden; } /*動画を囲んでいるdiv目一杯に広げる*/ .video iframe, .video object, .video embed, .instagram iframe, .instagram object, .instagram embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
このスタイルを貼り付けると、以下のように幅に合わせてiframeが表示されるようになります。
Instagramでもちゃんとレスポンシブ表示されます。
まとめ
この方法は、コピペを2回行うだけでできるので、結構簡単に実装出来るのではないかと思います。
正規表現は、もっと厳密な書き方も出来るかもしれませんが、とりあえず僕の環境では問題なく動作しています。もしうまくいかなかった場合には、正規表現チェッカーなどで新たな書き方を模索すれば良いかと思います。