web-dev-qa-db-ja.com

コンテナの残りの高さの100%に合うようにIframeを作成する

バナーとiframeを使ってWebページをデザインしたいです。ブラウザのサイズ変更に合わせて、iframeが残りのページの高さすべてを埋めて自動的にサイズ変更できることを願います。 Javascriptコードを書かずにCSSだけで完成させることは可能ですか?

height:100%をiframeに設定しようとしましたが、結果はかなり近くなりましたが、iframeはbanner div要素の30pxの高さも含めて、ページ全体の高さを埋めようとしたため、不要な垂直スクロールバーが表示されました。それは完璧ではありません。

アップデートノート:質問をうまく説明していないことをお詫び申し上げます。Webページの余白の高さ全体を占めるようにDIVのCSSマージン、パディング属性を試してみました。しかし、トリックはiframeには作用しませんでした。

 <body>
    <div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
    <iframe src="http: //www.google.com.tw" style="width:100%; height:100%;"></iframe>
</body>

任意のアイデアは大歓迎です。

219
Darkthread

2019年に更新

TL; DR:今日の最良の選択肢は、この回答の最後の選択肢です - flexbox。すべてがそれをうまくサポートし、何年もの間持っています。それを求めて振り返らないでください。この答えの残りは歴史的な理由のために残されています。


その秘訣は、100%が何からとられているのかを理解することです。 CSSスペックを読むことはそこであなたを助けることができます。

長い話を短くするために - 「包含ブロック」のようなものがあります - これは親要素である必要はありません。簡単に言うと、それはposition:relativeまたはposition:absoluteを持つ階層の最初の要素です。他に何もない場合は、body要素そのもの。したがって、「width:100%」と言うと、「包含ブロック」の幅をチェックして、要素の幅を同じサイズに設定します。そこに何か他のものがあったなら、あなたはそれ自身よりも大きい(したがって「オーバーフローする」)「包含ブロック」の内容を取得するかもしれません。

身長も同じように機能します。 1つ例外があります。ブラウザウィンドウの100%の高さにはなれません。それに対して100%を計算できる最上位の要素はbody(またはhtml?不明)要素であり、その内容を格納するのに十分なだけ拡張されています。 height:100%を指定しても効果はありません。100%を測定するための「親要素」がないためです。ウィンドウ自体は重要ではありません。 ;)

何かをウィンドウのちょうど100%に広げるには、2つの選択肢があります。

  1. JavaScriptを使う
  2. DOCTYPEを使わないでください。これは良い習慣ではありませんが、ブラウザを "奇妙なモード"にします。このモードでは、要素に対してheight = "100%"を実行でき、ウィンドウサイズに合わせて拡大されます。 DOCTYPEの変更に対応するために、ページの残りの部分もおそらく変更する必要があることに注意してください。

更新:私がこれを投稿したときに私がすでに間違っていなかったかどうかはわかりませんが、これは確かに現在古くなっています。今日、あなたはこれをあなたのスタイルシートの中で行うことができます:html, body { height: 100% }そしてそれは実際にあなたのビューポート全体に広がるでしょう。 DOCTYPEを使っても。状況によっては、min-height: 100%も役に立ちます。

そして私は、誰かに癖モードのドキュメントを作成するようにアドバイスすることもしません。ブラウザごとに異なるモードがあるため、ページをブラウザ間で一貫して表示することは2桁難しくなります。 DOCTYPEを使用してください。常に。できればHTML5 - <!DOCTYPE html>。覚えるのは簡単で、10歳のブラウザでさえも、すべてのブラウザで魅力のように機能します。

唯一の例外は、あなたがIE5か何かのようなものをサポートしなければならないときです。あなたがそこにいるならば、あなたはとにかくあなた自身の上にいます。これらの古代のブラウザは今日のブラウザのようなものではありません、そしてここで与えられる少しのアドバイスもそれらを手助けするでしょう。明るい面では、あなたがそこにいるなら、あなたはおそらくただ一つの種類のブラウザをサポートしなければならない、それは互換性の問題を取り除く。

がんばろう!

更新2:ねえ、それは久しぶりです! 6年後、新しい選択肢が登場しました。私は以下のコメントで議論をしました、今日のブラウザで動作するあなたのためのより多くのトリックはここにあります。

オプション1 - 絶対位置。あなたが最初の部分の正確な高さを知っているときのために素晴らしくてきれい。

body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.first-row {position: absolute;top: 0; left: 0; right: 0; height: 100px; background-color: Lime;}
.second-row {position: absolute; top: 100px; left: 0; right: 0; bottom: 0; background-color: red }
.second-row iframe {display: block; width: 100%; height: 100%; border: none;}
<div class="first-row">
  <p>Some text</p>
  <p>And some more text</p>
</div>
<div class="second-row">
  <iframe src="https://jsfiddle.net/about"></iframe>
</div>

いくつかの注意 - second-rowbottom: 0は何らかの理由でiframeに対して機能しないため、right: 0コンテナが必要です。 「置き換えられた」要素であることに関係する何か。しかしwidth: 100%height: 100%は問題なく動作します。 display: blockはデフォルトでinline要素であり、そうでなければ空白文字が奇妙なオーバーフローを起こし始めるので必要です。

オプション2 - テーブル。最初の部分の高さがわからないときに機能します。実際の<table>タグを使うことも、display: tableを使って手の込んだやり方ですることもできます。最近流行しているようですので、私は後者のために行きます。

body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.row-container {display: table; empty-cells: show; border-collapse: collapse; width: 100%; height: 100%;}
.first-row {display: table-row; overflow: auto; background-color: Lime;}
.second-row {display: table-row; height: 100%; background-color: red; overflow: hidden }
.second-row iframe {width: 100%; height: 100%; border: none; margin: 0; padding: 0; display: block;}
<div class="row-container">
  <div class="first-row">
    <p>Some text</p>
    <p>And some more text</p>
  </div>
  <div class="second-row">
    <iframe src="https://jsfiddle.net/about"></iframe>
  </div>
</div>

いくつかの注意 - overflow: autoは、行が常にその内容のすべてを含むことを確認します。そうでなければ、浮動要素は時々オーバーフローする可能性があります。 2行目のheight: 100%は、最初の行をできるだけ小さくすることができる範囲で確実に拡張します。

オプション3 - flexbox。それらすべての中で最もきれいなものですが、それほど素晴らしいブラウザサポートはありません。 IE10はflexboxプロパティのために-ms-接頭辞を必要とするでしょう、そして、それ以下はそれを全くサポートしないでしょう。

body, html {width: 100%; height: 100%; margin: 0; padding: 0}
.row-container {display: flex; width: 100%; height: 100%; flex-direction: column; background-color: blue; overflow: hidden;}
.first-row {background-color: Lime; }
.second-row { flex-grow: 1; border: none; margin: 0; padding: 0; }
<div class="row-container">
  <div class="first-row">
    <p>Some text</p>
    <p>And some more text</p>
  </div>
  <iframe src="https://jsfiddle.net/about" class="second-row"></iframe>
</div>

いくつかの注意 - overflow: hiddenは、この場合display: blockがあってもiframeが依然としてある種のオーバーフローを生成するためです。フルスクリーンビューやスニペットエディタには表示されませんが、小さなプレビューウィンドウには余分なスクロールバーが表示されます。それが何であるかわかりません、iframeは変です。

191
Vilx-

この問題を解決するためにJavaScriptを使用します。ここに源があります。


var buffer = 20; //scroll bar buffer
var iframe = document.getElementById('ifm');

function pageY(elem) {
    return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
}

function resizeIframe() {
    var height = document.documentElement.clientHeight;
    height -= pageY(document.getElementById('ifm'))+ buffer ;
    height = (height < 0) ? 0 : height;
    document.getElementById('ifm').style.height = height + 'px';
}

// .onload doesn't work with IE8 and older.
if (iframe.attachEvent) {
    iframe.attachEvent("onload", resizeIframe);
} else {
    iframe.onload=resizeIframe;
}

window.onresize = resizeIframe;

注:ifmはiframe IDです

pageY()はJohn Resig(jQueryの作者)によって作成されました。

65
MichAdel

これを行うもう1つの方法は、親ノードでposition: fixed;を使用することです。
私が間違っていなければ、position: fixed;は要素をviewportに結び付けます。したがって、このノードにwidth: 100%;およびheight: 100%;プロパティを指定すると、画面全体に広がります。これ以降は、単純な<iframe> CSS命令を使用して、width: 100%; height: 100%;タグをその中に置き、残りのスペース(幅と高さの両方)にまたがることができます。

コード例


    body {
        margin: 0px;
        padding: 0px;
    }

    /* iframe's parent node */
    div#root {
        position: fixed;
        width: 100%;
        height: 100%;
    }

    /* iframe itself */
    div#root > iframe {
        display: block;
        width: 100%;
        height: 100%;
        border: none;
    }
   <html>
        <head>
            <title>iframe Test</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head>
        <body>
            <div id="root">
                <iframe src="http://stackoverflow.com/">
                    Your browser does not support inline frames.
                </iframe>
            </div>
        </body>
    </html>
45
D1SoveR

あなたはそれをDOCTYPEで行うことができますが、あなたはtableを使わなければなりません。これをチェックしてください。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style>
*{margin:0;padding:0}
html, body {height:100%;width:100%;overflow:hidden}
table {height:100%;width:100%;table-layout:static;border-collapse:collapse}
iframe {height:100%;width:100%}

.header {border-bottom:1px solid #000}
.content {height:100%}
</style>
</head>
<body>
<table>
    <tr><td class="header"><div><h1>Header</h1></div></td></tr>
    <tr><td class="content">
        <iframe src="http://google.com/" frameborder="0"></iframe></td></tr>
</table>
</body>
</html>
37
ducu

ここにいくつかの現代的なアプローチがあります:



  • アプローチ2 - Flexboxのアプローチ

    ここでの例

    共通の親要素のdisplayflex-direction: columnと共にflexに設定します(要素を互いの上に積み重ねることを想定しています)。次に、残りのスペースを埋めるために、子のiframeエレメントにflex-grow: 1を設定します。

    body {
        margin: 0;
    }
    .parent {
        display: flex;
        flex-direction: column;
        min-height: 100vh;
    }
    .parent .banner {
        background: #f00;
        width: 100%;
        height: 30px;
    }
    .parent iframe {
        background: #000;
        border: none;
        flex-grow: 1;
    }
    <div class="parent">
        <div class="banner"></div>
        <iframe></iframe>
    </div>

    このアプローチは サポートが少ないので1、私は前述のアプローチで行くことをお勧めします。

1Chrome/FFでは動作するようですが、IEでは動作しません(最初の方法は現在のすべてのブラウザで動作します)。

33
Josh Crozier

たぶんこれはすでに答えられています(上のいくつかの答えはこれを行うための「正しい」方法です)、しかし私は私も私の解決策を追加することを考えた。

私たちのiFrameはdiv内にロードされているので、window.height以外に何かが必要でした。そして私たちのプロジェクトがすでにjQueryに大きく依存しているのを見て、私はこれが最も洗練された解決策であると思います:

$("iframe").height($("#middle").height());

もちろん "#middle"はdivのidです。ユーザーがウィンドウのサイズを変更するたびに、このサイズの変更を思い出すだけで済みます。

$(window).resize(function() {
    $("iframe").height($("#middle").height());
});
17
Tim Geerts

これが私がしたことです。私は同じ問題を抱えていて、結局何時間もの間リソースをウェブで捜していました。

<style type="text/css">
   html, body, div, iframe { margin:0; padding:0; height:100%; }
   iframe { position:fixed; display:block; width:100%; border:none; }
</style>

これをヘッドセクションに追加しました。

私のiframeは3行1列のテーブルの真ん中のセルの内側にあります。

7
Danut Milea

MichAdelのコードは私のために働きますが、私はそれが正しく働くようにするためにいくつかのマイナーな修正を加えました。

function pageY(elem) {
    return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
}
var buffer = 10; //scroll bar buffer
function resizeIframe() {
    var height = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
    height -= pageY(document.getElementById('ifm'))+ buffer ;
    height = (height < 0) ? 0 : height;
    document.getElementById('ifm').style.height = height + 'px';
}
window.onresize = resizeIframe;
window.onload = resizeIframe;
6
asimrafi

以下を試してください。

<iframe name="" src="" width="100%" style="height: 100em"/>

それは私のために働いた

4
sree

あなたはこのようにhtml/cssでこれをすることができます:

<body>
    <div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
    <iframe src="http: //www.google.com.tw" style="position:fixed;top:30px;bottom:0px;width:100%;"></iframe>
</body>
3
vdbuilder

そうです、あなたはそのコンテナに対して100%の高さの尊重を持ったiframeを見せています:本体。

これを試して:

<body>
  <div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
  <div style="width:100%; height:90%; background-color:transparent;">
    <iframe src="http: //www.google.com.tw" style="width:100%; height:100%;">
    </iframe> 
  </div>
</body>

もちろん、2番目のdivの高さを必要な高さに変更します。

3
ARemesal

私はdisplay:tableを使って同様の問題を解決しました。小さな垂直スクロールバーを残して、それはほとんど働きます。その柔軟な列にiframe以外のものを追加しようとしている場合はうまくいきます(

以下のHTMLを取る

<body>
  <div class="outer">
    <div class="banner">Banner</div>
    <div class="iframe-container">
      <iframe src="http: //www.google.com.tw" style="width:100%; height:100%;border:0;"></iframe>
    </div>
  </div>
</body>

Display:tableを使用するように外側のdivを変更し、幅と高さが設定されていることを確認します。

.outer {
  display: table;
  height: 100%;
  width: 100%;
}

バナーをテーブル行にして、好みの高さに設定します。

.banner {
  display: table-row;
  height: 30px;
  background: #eee;
}

Iframeの周囲に余分なdivを追加して(または必要なコンテンツをすべて)、高さを100%に設定したテーブル行にします(高さを埋めるためにiframeを埋め込む場合は高さを設定することが重要です)。

.iframe-container {
  display: table-row;
  height: 100%;
}

以下はjsfiddleが仕事中にそれを示している(iframeがないのでそれはフィドルではうまくいかないようだから)

https://jsfiddle.net/yufceynk/1/

2
daamsie

HTML5の新機能:calc(高さ)を使う

<html style="width:100%; height:100%; margin: 0px; padding: 0px;">
<body style="width:100%; height:100%; margin: 0px; padding: 0px;">
<div style="width:100%; height:30px; background-color:#cccccc;">Banner</div>
<iframe src="http://www.google.com.tw" style="width:100%; height: calc(100% - 30px);"></iframe>
</body>
</html>
2
Stefan Steiger

@ MichAdelの同様の答えですが、私はJQueryを使用しています。

<script type="text/javascript">
    $(document).ready(function() {
        var $iframe = $('#iframe_id')[0];

        // Calculate the total offset top of given jquery element
        function totalOffsetTop($elem) {
            return $elem.offsetTop + ($elem.offsetParent ? totalOffsetTop($elem.offsetParent) : 0);
        }

        function resizeIframe() {
            var height = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
            height -= totalOffsetTop($iframe);
            $iframe.height = Math.max(0, height) + 'px';
        }

        $iframe.onload = resizeIframe();
        window.onresize = resizeIframe;
    });
</script>

iframe_idはiframeタグのIDです

1
Roy Shmuli

CSSルートをしばらく試した後、私はjQueryでかなり基本的なことを書いて自分の仕事をしました。

function iframeHeight() {
    var newHeight = $j(window).height();
    var buffer = 180;     // space required for any other elements on the page 
    var newIframeHeight = newHeight - buffer;
    $j('iframe').css('height',newIframeHeight);    //this will aply to all iframes on the page, so you may want to make your jquery selector more specific.
}

// When DOM ready
$(function() {
    window.onresize = iframeHeight;
}

IE8、Chrome、Firefox 3.6でテスト済み

1
benb

下記のコードで動作します

<iframe src="http: //www.google.com.tw"style="position: absolute; height: 100%; border: none"></iframe>
1
mallikgm

ここに概念的な問題があると思います。言うなら、 "iframeでset height:100%を試みたが、結果はかなり近いが、iframeはページ全体を埋めようとした" "100%"は "全体"と等しくありませんか?

Iframeにそのコンテナー(本体)の高さ全体を埋めるように依頼しましたが、残念ながら、<div>にブロックレベルの兄弟があり、その上に30pxの大きさがあるように依頼しています。そのため、親コンテナの合計は100%+ 30px> 100%にサイズ変更するよう求められています。それ故にスクロールバー。

あなたが意味を意味しているのは、iframeを消費して欲しいということです残りの部分枠や表のセルのように、height = "*"のようにすることができます。 IIRCこれは存在しません。

残念ながら、私の知る限りでは絶対単位と相対単位のどちらも効果的に混合/計算/減算する方法はないので、2つの選択肢に絞られていると思います。

  1. あなたのdivを絶対に配置してください。そうすれば、iframeだけでコンテナの高さが消費されます。これは他のあらゆる問題を抱えていますが、おそらく不透明度や配置は問題ないでしょう。

  2. あるいは、divの高さを%で指定し、その分iframeの高さを減らす必要があります。絶対的な高さが本当に重要な場合は、代わりにdivの子要素にそれを適用する必要があります。

1
annakata

"seamless"属性は、この問題を解決することを目的とした新しい標準です。

http://www.w3schools.com/tags/att_iframe_seamless.asp

この属性を割り当てると、境界線とスクロールバーが削除され、iframeのサイズがコンテンツのサイズになります。 Chromeと最新のSafariでのみサポートされていますが

これについての詳細はこちら: HTML5 iFrameシームレス属性

0
user2254487

あるいは、昔の学校に行って フレームセット を使用することもできます。

<frameset rows="30,*">
  <frame src="banner.swf"/>
  <frame src="inner.html" />
</frameset>
0
Amir Arad

私はCSSの位置を使用してこのシナリオを達成するための最良の方法だと思います。あなたの親divおよびpositionに対する絶対位置をあなたのiframeに対して絶対に設定してください。

.container{
  width:100%;
  position:relative;
  height:500px;
}

iframe{
  position:absolute;
  width:100%;
  height:100%;
}
<div class="container">
  <iframe src="http://www.w3schools.com">
  <p>Your browser does not support iframes.</p>
 </iframe>
</div>

他のパディングとマージンの問題については、今日css3 calc()は非常に高度で、ほとんどすべてのブラウザと互換性があります。

check calc()

0
Jay Patel

簡単なjQueryソリューション

Iframeページ内のスクリプトでこれを使用してください

$(function(){

    if(window != top){
        var autoIframeHeight = function(){
            var url = location.href;
            $(top.jQuery.find('iframe[src="'+ url +'"]')).css('height', $('body').height()+4);
        }
        $(window).on('resize',autoIframeHeight);
        autoIframeHeight();
    }

}
0
UnLoCo

ロードされるiframeのコンテンツにアクセスできる場合は、サイズが変更されるたびに親にサイズ変更を行うように指示できます。

    $(window).resize(function() {
        $(parent.document)
            .find("iframe")
            .css("height", $("body").css("height"));        
    }).trigger("resize");

ページに複数のiframeがある場合は、正しいものを選択するように、idなどの賢い方法を使用して.find( "iframe")を強化する必要があります。

0
Stephen

私はJSがより良い選択肢のように思われることに同意しますが、私はややCSSのみの実用的な解決策を持っています。欠点は、iframe htmlドキュメントに頻繁にコンテンツを追加する必要がある場合は、1パーセントの時間で調整する必要があることです。

溶液:

Html文書の両方に高さを指定しないで試してください

html, body, section, main-div {}

その後、これだけをコーディングします。

#main-div {height:100%;}
#iframe {height:300%;}

注意:divがあなたのメインセクションです。

これは比較的うまくいくはずです。 iframeは表示ウィンドウの高さの300%を正確に計算します。 (iframe内の)2番目のドキュメントのHTMLコンテンツの高さが、ブラウザの高さの3倍より小さい場合は、問題ありません。その文書に頻繁にコンテンツを追加する必要がない場合、これは恒久的な解決策であり、コンテンツの高さに応じて必要な独自の%を見つけることができます。

これは、2番目のhtmlドキュメント(埋め込まれたもの)がその高さを親のhtmlドキュメントから継承するのを防ぐために機能します。両方に高さを指定しなかったので、それはそれを防ぎます。子に%を与えると、その親を探します。そうでない場合は、そのコンテンツの高さになります。他のコンテナに高さが与えられていない場合に限り、私が試したものから。

0
pixelfe

これを行うには、ロード/サイズ変更イベントのボディサイズを測定し、高さを(全高 - バナーの高さ)に設定します。

現在のIE 8 Beta 2では、このイベントは現在IE 8 Beta 2では壊れているため、このonresizeを実行することはできません。

0
scunliffe

親の身長は100%ではないので、iframeの高さを%で設定することはできません。親の身長を100%にしてから、iframeの高さを100%にします。

For eg.
<html>
<head>
<style>
html,body{height:100%}
</style> 
</head>
<body>
<iframe src="http://www.quasarinfosystem.com" height="100%" width="100%" ></iframe>
</body>
</html>
0
Pravin Abhale

どうしてこれをしないでください(ボディパディング/マージンのためのわずかな調整で)

<script>
  var oF = document.getElementById("iframe1");
  oF.style.height = document.body.clientHeight - oF.offsetTop - 0;
</script>
0
access_granted