Asial Blog

Recruit! Asialで一緒に働きませんか?

外部コンテンツをiframeサイズで拡大縮小させたり、固定幅コンテンツをウィンドウサイズでピッタリ表示させる方法

カテゴリ :
フロントエンド(HTML5)
タグ :
Tech
HTML5
JavaScript
CSS3
クロスブラウザ
こんにちは、鴨田です。
タイトルが長くなってしまってすみません。

皆さんの中で、自分のサイトコンテンツの中で、
iframeを使って外部サイト(自分で更新できない)を表示したいときに、
iframe内のコンテンツを拡大縮小出来なくて困ったことがあったり、
サイトコンテンツをレスポンシブレイアウトではなく、
固定幅のまま、あらゆるブラウザで、
ウィンドウサイズに合わせてピッタリに拡大縮小したい、
と思ったことがある人はいないでしょうか?

前置きが大変長くなりましたが、
そんなことがあったけど出来なくて諦めたとか、
これからそんなことをしないといけないという方がいたら、
是非とも参考にしてください。



iframe内コンテンツの拡大縮小



例えば、このアシアルブログを横幅600px内でピッタリ縮小表示したい、
と思ったとき、どうすればよいでしょうか。

まず思いつくのは、cssのzoomを使って、縮小してみる方法です。

アシアルブログの横幅は1090pxとなっているので、
600/1090=0.55となるので、0.55倍するとピッタリ表示されるはずです。

高さはとりあえず600pxにしておきます。

HTML
  1. <iframe src="http://blog.asial.co.jp" frameborder="1" width="600" height="600"></iframe>
  2. <iframe src="http://blog.asial.co.jp" frameborder="1" width="600" height="600" style="zoom:0.55"></iframe>

通常




zoom:0.55



悲しいことに、iframeの横幅・縦幅が0.55倍になるだけで、
iframe内のコンテンツが縮小されるわけではないのです。
Firefoxなどのブラウザでは、そもそもzoomすらされていない状態になります。
また、iOSではそもそもiframeの幅指定を無視します。

ではどうすればよいのでしょうか?

答えとしては、CSS3が解釈できるブラウザ限定にはなりますが、
CSS3のtransformを使えばいいのです。

HTML
  1. transform:scale(0.55)<br>
  2. <iframe src="http://blog.asial.co.jp" frameborder="1" width="1090" height="1090" style="transform:scale(0.55);-o-transform:scale(0.55);-webkit-transform:scale(0.55);-moz-transform:scale(0.55);-ms-transform:scale(0.55);"></iframe>

transform:scale(0.55)



こうなります。
でもまだおかしいのです。上下左右にマージンがあります。
これは意図した物ではありません、tranformの起点がコンテンツの真ん中にあるためです。
これを補正するために、スタイルを追加します。

HTML
  1. <iframe src="http://blog.asial.co.jp" frameborder="1" width="1090" height="1090" style="transform:scale(0.55);-o-transform:scale(0.55);-webkit-transform:scale(0.55);-moz-transform:scale(0.55);-ms-transform:scale(0.55);transform-origin:0 0;-o-transform-origin:0 0;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;"></iframe>

transform:scale(0.55);transform-origin:0 0;



これでtranformの起点が左上になるので、意図したとおりの表示になりました。
後は、横方向にスクロールバーが出ているのが気になるのと、
まだiframeの右側と下側に大きくマージンが出来てしまっているので、
これを隠して上げる必要があります。

transformの起点は左上になりましたが、
コンテンツサイズは元のままとなっているためです。

HTML
  1. <div style="width:600px;height:600px;overflow-x:hidden;border:1px solid #999">
  2.     <div style="width:600px;height:3081px;overflow:hidden;">
  3.         <iframe src="http://blog.asial.co.jp" frameborder="0" scrolling="no" width="1090" height="5603" style="transform:scale(0.55);-o-transform:scale(0.55);-webkit-transform:scale(0.55);-moz-transform:scale(0.55);-ms-transform:scale(0.55);transform-origin:0 0;-o-transform-origin:0 0;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;"></iframe>
  4.     </div>
  5. </div>



二つほどdivの入れ子をする必要があります。
最初のdivは、実際の表示エリアになります、ボーダーと縦方向のスクロールを設定します。
2つめのdivは、コンテンツの高さを決めます、5603/0.55=3081pxです。スクロールなしに設定します。
最後にiframeとして、ボーダーなし、スクロールなし、高さと幅をコンテンツサイズとして、transformです。

最後にどういったときにこれを使うのかというと、
WEBアプリなどで、外部サイトだがアプリの一部として表示させたい、
などといったときに使えるかと思います。

基本的にCSS3が使えるブラウザであれば、動作するはずですが、
Androidの場合、端末によって、WebViewで動作しないことがあるようです。

※初出時に、ベンダープリフィクスを書いていなかったので追記しています。



固定幅レイアウトのページをウィンドウサイズでピッタリ表示させる



例えば、このアシアルブログをウィンドウサイズ600pxのときでも、
スクロールを出さずに、コンテンツサイズを縮小させて表示させたい、
と思ったとき、どうすればよいでしょうか。

まず思いつくのは、cssのzoomを使って、縮小してみる方法です。

アシアルブログの横幅は1090pxとなっているので、
600/1090=0.55となるので、0.55倍するとピッタリ表示されるはずです。

そうです、iframeのときと要領は同じです。
ですが、cssのzoomを使うだけではなく、viewportやjavaScript(jQuery)を駆使する必要があります。

なお、対応ブラウザは、Chrome、Mobile Chrome、Safari、Mobile Safari、Firefox、IE9~11です。
IE8にも対応させたいのですが、うまい方法が見つかっていません。
MsFilterが動作すればいいのですが、何故かうまいこといきません。
いい方法があれば、教えてもらえると大変嬉しいです。

  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <title>アシアルブログ</title>
  8. <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
  9. <script>
  10. // UA判定用
  11. var userAgent = window.navigator.userAgent.toLowerCase();
  12. var appVersion = window.navigator.appVersion.toLowerCase();
  13. // ロード・リサイズ時に画面最適化
  14. $(window).bind("load resize", function(){
  15.     var width = $(window).width();
  16.     $("html").css("zoom" , width/1090);
  17.     if (appVersion.indexOf("msie 9.") != -1) {
  18.         $("html").css("-ms-transform" , "scale(" + width/1090 + ")").css("-ms-transform-origin" , "0 0");
  19.         $("body").css("overflow-x" , "hidden");
  20.     } else if (userAgent.indexOf('gecko') != -1) {
  21.         $("html").css("-moz-transform" , "scale(" + width/1090 + ")").css("-moz-transform-origin" , "0 0");
  22.         $("body").css("overflow-x" , "hidden");
  23.     }
  24. });
  25. </script>
  26. <style>
  27. /* IE用viewport */
  28. @-ms-viewport {width: 1090px;}
  29. /* common */
  30. html,body {margin:0;padding:0}
  31. </style>
  32. </head>
  33. <body>
  34.     <img src="blog.jpg" width="1090">
  35. </body>
  36. </html>

HTML、JavaScript、CSSに関して、
それぞれ説明を行います。

  1. <meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

viewportの設定です。
一般的なものとなりますので、特に注意事項はありません。
Chrome、Mobile Chrome、Safari、Mobile Safari、Firefoxで有効です。

IEに関しては、metaのviewport設定では対応していませんので、
CSSで下記の指定をします。なお、IE10以降で有効です。

  1. /* IE用viewport */
  2. @-ms-viewport {width: 1090px;}

こちらはdevice-widthでは、正常動作しなかったので、
コンテンツサイズとしてください。

続いて、JavaScriptです。

  1. <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

jQueryを読み込みます。バージョンは必要に応じて変えてください。

  1. // UA判定用
  2. var userAgent = window.navigator.userAgent.toLowerCase();
  3. var appVersion = window.navigator.appVersion.toLowerCase();

UsetAgent判定を行う必要があるので、
ブラウザ名とバージョンを取得します。

  1. // ロード・リサイズ時に画面最適化
  2. $(window).bind("load resize", function(){
  3. // 中身
  4. });

ページロード時とウィンドウリサイズ時に処理を行います。

  1. var width = $(window).width();

ウィンドウ幅を取得します。

  1. $("html").css("zoom" , width/1090);

ウィンドウ幅をコンテンツサイズ(1090px)で割った数値を、
htmlのzoomに設定することで、コンテンツサイズがウィンドウサイズと同じになります。
Chrome、Mobile Chrome、Safari、Mobile Safariはこの設定だけで動作します。

  1. if (appVersion.indexOf("msie 9.") != -1) {
  2.     $("html").css("-ms-transform" , "scale(" + width/1090 + ")").css("-ms-transform-origin" , "0 0");
  3.     $("body").css("overflow-x" , "hidden");
  4. } else if (userAgent.indexOf('gecko') != -1) {
  5.     $("html").css("-moz-transform" , "scale(" + width/1090 + ")").css("-moz-transform-origin" , "0 0");
  6.     $("body").css("overflow-x" , "hidden");
  7. }

Firefox、IE9に関しては、htmlに対するzoomが効かないようなので、
zoomの代わりに、transform:scaleを使用することで同じ効果が得られます。
また、横方向のスクロールバーが出てくるため、
bodyに対して、overflow-x:hiddenを設定します。

  1. <img src="blog.jpg" width="1090">

最後にコンテンツですが、今回はデモなので1090pxの画面キャプチャとしました。

最後に、実際どのように表示されるのか見てみたいと思います。

デモページ(クリックで別ウィンドウで起動します)


幅600pxのiframeで表示しているだけですが、自動的にサイズ調整されているのが分かります。

※iOSなどだと、iframeが自動的にコンテンツサイズにされてしまうので、
 iframeの方だと正常動作していませんが、デモページの方は問題ありません。



以上です。

調べても、こういった使い方をしている人があまり見あたらないので、
レアケースな実装なのかも知れませんが、なんとなく使い道があると思いますので、
参考になればと思います。