iframeをコンテナの残りの高さの100%に合わせる


260

バナーとiframeを使用してWebページをデザインしたい。iframeが残りのすべてのページの高さを埋め、ブラウザのサイズが変更されると自動的にサイズ変更されることを願っています。CSSでのみ、JavaScriptコードを記述せずにそれを実行することは可能ですか?

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

更新メモ:質問をうまく説明できなかったので失礼します。CSVマージンを試し、DIVでパディング属性を使用して、Webページの再配置高さ全体を正常に占有しましたが、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>

どんなアイデアでも大歓迎です。

回答:


236

2019年に更新

TL; DR:今日の最良の選択肢は、この回答の最後の1つ、フレックスボックスです。すべてがそれをうまくサポートし、何年も持っています。そのために行き、振り返ってはいけません。この答えの残りは歴史的な理由のために残されています。


秘訣は、100%が何に使用されているかを理解することです。CSSの仕様を読むことは、そこで役立ちます。

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

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

何かをウィンドウの100%正確に拡大するには、2つの選択肢があります。

  1. JavaScriptを使用する
  2. DOCTYPEは使用しないでください。これは良い方法ではありませんが、ブラウザを「クイズモード」に設定します。このモードでは、要素に対してheight = "100%"を実行でき、要素をウィンドウサイズに拡大します。DOCTYPEの変更に対応するには、ページの残りの部分も変更する必要があることに注意してください。

更新:これを投稿したとき、私が間違っていなかったかどうかはわかりませんが、これは確かに時代遅れです。今日、これをスタイルシートで実行できhtml, body { height: 100% }ます。実際には、ビューポート全体に拡大されます。DOCTYPEでも。min-height: 100%状況によっては、これも役立つ場合があります。

そして、私は奇妙なモードのドキュメントを作るように誰にも助言しませんません。なぜなら、解決するよりもずっと頭痛の種になるからです。ブラウザーごとに異なる癖モードがあるため、ブラウザー間でページを一貫して表示することは2桁難しくなります。DOCTYPEを使用します。常に。HTML5 oneが望ましい<!DOCTYPE html>。覚えやすく、10歳のブラウザを含め、すべてのブラウザで魅力的な動作をします。

唯一の例外は、IE5のようなものをサポートする必要がある場合です。あなたがそこにいるのなら、あなたはとにかくあなた自身でいます。これらの古くからあるブラウザーは、今日のブラウザーとは異なり、ここに記載されているアドバイスはほとんどありません。明るい面を言えば、互換性の問題を取り除く1種類のブラウザーをサポートする必要があるだけです。

幸運を!

更新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-rowコンテナがあるために必要とされるbottom: 0right: 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行は常にその内容のすべてを含むことを確認します。そうしないと、浮動要素がオーバーフローすることがあります。height: 100%2行目は、それを取得としてそれは小さなとして最初の行を絞ることができます限り必ずそれが拡大します。

オプション3-フレックスボックス。それらの中で最もクリーンなものですが、優れたブラウザのサポートはありません。IE10は-ms-flexboxプロパティのプレフィックスを必要とし、それより少ないものはそれをまったくサポートしません。

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: hiddendisplay: block、この場合でもiframeが何らかのオーバーフローを生成するためです。全画面表示やスニペットエディタでは表示されませんが、小さなプレビューウィンドウには追加のスクロールバーが表示されます。それが何であるかわからない、iframeは奇妙です。


@sproketboyさて、それはW3Cの推奨事項です。そして、それは最悪の事態でもなく、長い道のりでもありません。
John

これを、IFrameのページのスタイルシート、またはIFrameを含む親ページのスタイルシートに配置しますか?
Mathias Lykkegaard Lorenzen、2015

1
それは素晴らしいです、ありがとう!フレックスボックスは確かに最もクリーンですが、テーブルは学習するのにも最適で、オーバーフローなしで機能しているようです。jsfiddle.net
Dmitri Zaitsev

1
最新の更新をこの回答の一番上に移動する価値があるかもしれません。最良の答えであるflexboxにたどり着くためには、すべてをやり通さなければなりませんでした。
forgivenson

2
@forgivenson-十分だ。この回答の冒頭にメモを追加しました。
Vilx-

68

この問題を解決するために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の作者)によって作成されました


49

これを行う別の方法はposition: fixed;、親ノードで使用することです。
私が間違っていない場合はposition: fixed;、要素をビューポートに関連付けます。したがって、このノードwidth: 100%;height: 100%;プロパティを指定すると、画面全体に広がります。この時点から、<iframe>簡単な方法でタグをその中に入れ、残りのスペース(幅と高さの両方)に広げることができます。width: 100%; height: 100%; CSS命令を使用し広げることができます。

コード例


    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>


1
これは「残りの」高さをどのように取っていますか?
EricG、

3
position: fixediframeにも追加する必要があることに気づきました。
0xF 2014年

ありがとう、私のSSRSレポートの高さを修正し、自殺を別の日に回避しました。
Mike D

1
スクロールバーは表示されません
andrej '21

完全-css '>'について説明してもらえますか。例:div#root> iframe私はそれに慣れていないため、参照を見つけることができません
Datadimension

40

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



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

    ここの例

    displayとともに、共通の親要素のをflexに設定flex-direction: columnします(要素を互いの上に積み重ねたい場合)。次に、残りのスペースを満たすようにflex-grow: 1iframe要素を設定します。

    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、前述のアプローチを使用することをお勧めします。

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


3
作業とIMOの両方で、ここで説明する2つのオプションが最善のアプローチです。から差し引くスペースの量を知る必要があるflexboxので、私はこのオプションを好みます。では、簡単なことではありません。calcvhflexboxflex-grow:1
キルマイジング

39

でそれを行うこと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>

1
少なくともjsは必要ありません!! しかし、それはウェブセーフですか?
Ali Shakiba

1
このソリューションの欠点は、html、body {overflow:hidden;}がページスクロールを削除することです。
Ali Shakiba、2011年

上記のコードでフッターを追加しようとしていますが、フッターが表示されません。手伝ってくれませんか
Akshay Raut 2013年

18

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

私たちのiFrameはdiv内に読み込まれるため、window.height以外のものが必要でした。そして、私たちのプロジェクトはすでにjQueryに大きく依存しているので、これが最もエレガントなソリューションであることがわかりました。

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

もちろん、「#middle」はdivのIDです。あなたがしなければならない唯一の追加のことは、ユーザーがウィンドウのサイズを変更するたびに、このサイズの変更を思い出すことです。

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

7

これが私がしたことです。私も同じ問題を抱えており、何時間もウェブを検索してリソースを探していました。

<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列の表の中央のセル内にあることに注意してください。


コードは、IFRAMEを含むTDの高さが100%である場合にのみ機能します。すべてのdivの高さを100%にするスタイルがあるため、テーブルがDIV要素内に含まれている場合に機能します。
Nikola Petkanski、2011

6

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;

4

そうです、あなたはそのコンテナ、つまり本体に対して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の高さを必要な高さに変更します。


8
30px + 90%!= 100%
stepancheg 2010年

1
90%の代わりにcalc(100%-30px)を使用できます
Justin E

4

以下を試してください:

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

それは私のために働いた


4
親を埋めるのではなく、iframeの高さを大きくするだけです。
Ben

3

次のように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>

2

HTML5の新機能:計算を使用(高さで)

<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

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>

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

.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/


1

ここに概念的な問題があると思います。言って「私はセットの高さを試してみました:100%のiframeに、結果は非常に近いですが、IFRAMEは、ページ全体を埋めるためにしようとしました」「100%」「全体」に等しいされていないとき、よく、?

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

私はあなたが考える意味することは、あなたが消費するIFRAMEを好むだろうということです残っているもの、すなわち、高さ=「*」、フレームやテーブルセルのようにすることができます。IIRCこれは存在しません。

残念ながら、私の知る限りでは、絶対単位と相対単位を効果的に混合/計算/減算する方法もないため、次の2つのオプションに削減できます。

  1. divを絶対的に配置すると、コンテナーから取り出され、iframeだけでコンテナーの高さが消費されます。ただし、これにより他のあらゆる問題が発生しますが、おそらく不透明度や配置を調整することで問題ありません。

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


1

しばらく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

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

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

1

@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です


0

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

現在、IE8 Beta2では、イベントがIE8 Beta2で壊れているため、これをオンサイズ変更することはできません。


0

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

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

2
@vdbuilder:いいえ、それはHTML5より前のバージョンでのみ有効です。私はそれがまだ機能するに違いない。;-)
TJ Crowder

0

私はJSがより良いオプションのように思われることに同意しますが、私は多少CSSのみで機能するソリューションを持っています。その欠点は、iframe htmlドキュメントにコンテンツを頻繁に追加する必要がある場合、1パーセントのトラフ時間を調整する必要があることです。

解決:

HTMLドキュメントの高さを指定しないでください。

html, body, section, main-div {}

次に、これだけをコーディングします:

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

注:divがメインセクションである必要があります。

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

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


0

シームレス」属性は、この問題を解決することを目的とした新しい標準です。

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

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

詳細はこちら: HTML5 iFrameシームレス属性


シームレス属性はHTML 5仕様から削除されました。
エリックスタインボーン2016

0

単純なjQueryソリューション

iframedページ内のスクリプトでこれを使用します

$(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

親ボディの高さが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

読み込まれるiframeのコンテンツにアクセスできる場合は、サイズ変更するたびに親にサイズを変更するように指示できます。

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

ページに複数のiframeがある場合は、IDまたは他の巧妙な方法を使用して.find( "iframe")を拡張し、正しいものを選択する必要がある場合があります。


0

私はCSS位置を使用してこのシナリオを達成するための最良の方法だと思います。親divに相対的な位置を設定し、position:absoluteを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()は非常に高度で、ほとんどすべてのブラウザーと互換性があります。

calc()をチェックする


0

なぜこれをしないのですか(ボディのパディング/マージンを少し調整して)

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

あなたは交換する必要がある-0+'px'最後に。モバイルでも動作しますか?
Dmitri Zaitsev 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.