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の方だと正常動作していませんが、デモページの方は問題ありません。



以上です。

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

コメント

  • abu

    参考になりました。
    リンクで別ページ表示するより、縮小してでも同一ページ内にiframeで展開したい場合もありますよね。
    おかげで目的を達成できました。
    ありがとうございます。

  • 鴨田

    abu様
    あまり活用法がないかなと思っていたのですが、
    お役に立てたようで何よりです。
    感謝のお言葉頂き、大変ありがとうございます。

  • ゆうき

    これすごいです!!
    ポートフォリオとかで使ってみようと思います♪
    ありがとうございますm(__)m

  • 鴨田

    ゆうき様
    確かにポートフォリオとかでは役に立ちそうですね!
    役に立ったようで、記事を書いて良かったです。

  • F1

    iframe内の指定したidにcssを適応させたいのですが、どう記述していいのかわかりません。
    教えてください ><

  • 鴨田

    iframe内のhtmlでcssを記述するか、リンクすればいいのだと思います。
    iframeを表示している(親の)htmlで指定しても、効果がないはずです。
    試してみてください。

  • SAM

    ありがとー使わせてもらいました!

  • 鴨田

    お役に立てたようで良かったです。

  • 名無し

    自分のサイトに掲示板を設置するために、外部のレンタル掲示板を使い、それをiframeをつかって自サイトに表示して使っています。しかし、掲示板という特質上、絶えずコメントが追加されて、掲示板のページの長さが変わってしまい、iframeにあらかじめ設定しておいた高さとずれが生じ、スクロールバーが表示されてしまいます。
    外部コンテンツをiframeつかって表示する際にiframeの高さを自動的に外部コンテンツのページの長さに合わせることは可能でしょうか?

  • poyone

    おおお!これはすごいです。何かに使えそうな気がします。
    感動したのでコメントしました

  • fai

    おーこれはすごい。
    とても助かりました。

  • 鴨田

    コメントありがとうございます。
    大分前の記事なのですが、今も何かに役立てているようで、嬉しく思います。
    iframeはクリックジャッキングされたりもするので、
    セキュリティなどに気をつけつつ、使用していただければと思います。

  • 通りすがり

    >外部コンテンツをiframeつかって表示する際にiframeの高さを自動的に外部コンテンツのページの長さに合わせることは可能でしょうか?

    この件はJSで拾ってくるぐらいしか思いつかないなー

  • お財布 ブランド激安

    株式会社 スーパーコピーブランド激安市場

    ブランドコピー、ロレックスコピー、オメガコピー、ウブロコピー、ルイヴィトンコピー、シャネルコピー、グッチコピー、
    スーパーコピーなどです。バッグ、財布、キーケース、時計、ジュエリー、マフラー、ストール、靴下、小件などあります
    1.当社の目標は最高のインターネットサービスご提供することです.弊社は24時間営業、年中無休.
    2.品質を重視、納期も厳守、信用第一は当社の方針です.
    3.日本には無い商品,日本では高価な商品,弊社のない商品,取引先を代理して製造会社を連絡することができる.
    4.弊社長年の豊富な経験と実績があり.輸入手続も一切は弊社におまかせできます.ご希望の商品を責任を持ってお届けします

    是非ご覧ください!

    休業日: 365天受付年中無休
    [url=http://www.gowatchs.com/brand-261.html]お財布 ブランド激安[/url]

  • Se a senhora achar qualquer saudável ala dentre net dentro de residência, será capaz de colocar baixando múltiplos torrents, ou melhor, diversos filmes, séries, programas, games bem como etc, essencial ao mesmo tempo.

    Se a senhora achar qualquer saudável ala dentre net dentro de residência, será capaz de colocar
    baixando múltiplos torrents, ou melhor, diversos filmes, séries, programas, games bem como etc,
    essencial ao mesmo tempo. http://k71.saaa.co.th/phpinfo.php?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2FAnthony.guess%40php.sonne-Cie.de%2F%3Fa%255B%255D%3Dtorrents%2520downloads%2520sites%252C%2520%253Ca%2520href%253Dhttp%253A%252F%252FKaa.io%252F18da%253Ehttp%253A%252F%252FKaa.io%252F%253C%252Fa%253E%252C%3Ethe%20pirate%20filmes%20blu%20Ray%20brasil%3C%2Fa%3E

コメントフォーム



captcha_key

アシアルの会社情報

アシアル株式会社はPHP、HTML5、JavaScriptに特化したWebエンジニアリング企業です。ユーザーエクスペリエンス設計から大規模システム構築まで、アシアルメンバーが各々の専門性を通じてインターネットの進化に貢献します。

会社情報詳細

最近の記事