アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

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

こんにちは、鴨田です。
タイトルが長くなってしまってすみません。

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

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



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



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

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

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

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

HTML


<iframe src="http://blog.asial.co.jp" frameborder="1" width="600" height="600"></iframe>
<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


transform:scale(0.55)<br>
<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


<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


<div style="width:600px;height:600px;overflow-x:hidden;border:1px solid #999">
    <div style="width:600px;height:3081px;overflow:hidden;">
        <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>
    </div>
</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 ChromeSafari、Mobile SafariFirefoxIE9~11です。
IE8にも対応させたいのですが、うまい方法が見つかっていません。
MsFilterが動作すればいいのですが、何故かうまいこといきません。
いい方法があれば、教えてもらえると大変嬉しいです。



<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<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">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>アシアルブログ</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
// UA判定用
var userAgent = window.navigator.userAgent.toLowerCase();
var appVersion = window.navigator.appVersion.toLowerCase();
// ロード・リサイズ時に画面最適化
$(window).bind("load resize", function(){
    var width = $(window).width();
    $("html").css("zoom" , width/1090);
    if (appVersion.indexOf("msie 9.") != -1) {
        $("html").css("-ms-transform" , "scale(" + width/1090 + ")").css("-ms-transform-origin" , "0 0");
        $("body").css("overflow-x" , "hidden");
    } else if (userAgent.indexOf('gecko') != -1) {
        $("html").css("-moz-transform" , "scale(" + width/1090 + ")").css("-moz-transform-origin" , "0 0");
        $("body").css("overflow-x" , "hidden");
    }
});
</script>
<style>
/* IE用viewport */
@-ms-viewport {width: 1090px;}
/* common */
html,body {margin:0;padding:0}
</style>
</head>
<body>
    <a href="https://www.asial.co.jpblog.jpg &mode=1" class="popupimg"><img src="https://www.asial.co.jpblog.jpg"></a>
</body>
</html>


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



<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 ChromeSafari、Mobile SafariFirefoxで有効です。

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



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


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

続いて、JavaScriptです。



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


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



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


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



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


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



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


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



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


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



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


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



<a href="https://www.asial.co.jpblog.jpg &mode=1" class="popupimg"><img src="https://www.asial.co.jpblog.jpg"></a>


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

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

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


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

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



以上です。

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