Сделайте Iframe для приспособления 100% из высоты контейнера остальной

Я хочу создать веб-страницу с баннером и iframe. Я надеюсь, что iframe может заполнить всю оставшуюся высоту страницы и автоматически изменяться по мере изменения размера браузера. Можно ли сделать это без написания кода Javascript, только с помощью CSS?

я попробовал set height:100% на iframe результат довольно близок, но iframe попытался заполнить всю высоту страницы, включая 30px высота элемента banner div, поэтому я получил ненужную вертикальную полосу прокрутки. Это не идеальный.

Обновление Примечания: Извините, что не описал вопрос Хорошо, я попробовал CSS margin, атрибут заполнения на DIV, чтобы занять всю высоту реминирования веб-страницы успешно, но трюк не сработал на 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>

любая идея приветствуется.

26 ответов


фокус в том, чтобы понять, что за 100% берется. Чтение спецификаций CSS может помочь вам в этом.

чтобы сделать длинную историю короткой-есть такая вещь, как" содержащий блок " - который не является необходимым родительским элементом. Проще говоря, это первый элемент иерархии, который имеет положение:относительное или положение:абсолютное. Или сам элемент тела, если нет ничего другого. Итак, когда вы говорите " ширина: 100%", он проверяет ширину "содержащего блока" и устанавливает ширину ваш элемент одинакового размера. Если бы там было что-то еще, вы могли бы получить содержимое "содержащего блока", которое больше, чем само по себе (таким образом, "переполнено").

Высота работает таким же образом. за одним исключением. Вы не можете получить высоту в 100% окна браузера. Самый верхний элемент уровня, по которому можно вычислить 100%, - это тело (или html? не уверен) элемент, и это растягивается достаточно, чтобы содержать его содержимое. Задается высота:100% на нем будет никакого эффекта, потому что у него нет "родительского элемента", против которого можно измерить 100%. Само окно не считается. ;)

сделать что-то растянуть ровно на 100% окна, у вас есть два варианта:

  1. Использовать JavaScript
  2. не используйте DOCTYPE. Это не очень хорошая практика, но она помещает браузеры в "режим причуд", в котором вы можете делать height="100%" на элементах, и это растянет их до размера окна. Обратите внимание, что остальная часть вашей страницы будет вероятно, также нужно изменить, чтобы приспособиться к изменениям DOCTYPE.

обновление: я не уверен, что я не ошибся уже, когда я разместил это, но это, безусловно, устарело сейчас. Сегодня вы можете сделать это в своей таблице стилей:html, body { height: 100% } и это на самом деле растянется на весь ваш видовой экран. Даже с параметра "DOCTYPE". min-height: 100% также может быть полезно, в зависимости от вашей ситуации.

И не советовал бы никому делать причуды-режим документ больше, потому что это вызывает больше головных болей, чем решает их. Каждый браузер имеет разные причуды-режим, поэтому получить вашу страницу, чтобы смотреть последовательно через браузеры становится на два порядка сложнее. Использовать параметра "DOCTYPE". Всегда. Предпочтительно HTML5 one -<!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-row контейнер необходим, потому что bottom: 0 и right: 0 по какой-то причине не работает на iframes. Что-то связанное с тем, чтобы быть "замененным" элементом. Но!--12--> и height: 100% работает просто отлично. display: block is необходимо, потому что это 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 гарантирует, что строка всегда включает все его содержимое. В противном случае плавающие элементы могут иногда переполняться. The height: 100% на второй строке убедитесь, что он расширяется столько, сколько он может сжимая первый ряд так мало, как он получает.

3 - flexbox. Самый чистый из них всех, но с менее чем звездной поддержкой браузера. 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: hidden потому что iframe по-прежнему генерирует какое-то переполнение даже с display: block в этом случае. Он не отображается в полноэкранном режиме или редакторе фрагментов, но небольшое окно предварительного просмотра получает дополнительную полосу прокрутки. Понятия не имею, что это такое, если кадры странные.


мы используем 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() был создан Джоном Ресигом (автором jQuery)


другой способ сделать это - использовать position: fixed; на родительский узел.
Если я не ошибаюсь, position: fixed; связывает элемент с viewport, таким образом, как только вы даете этот узел width: 100%; и height: 100%; свойства, она будет охватывать весь экран. С этого момента, вы можете поставить <iframe> тег внутри него и охватить его над оставшимся пространством (как по ширине, так и по высоте) с помощью simple 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>

вы можете сделать это с помощью 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>

вот несколько современных подходов:



  • подход 2 - Flexbox подход

    Пример

    установить display общего родительского элемента в flex вместе с flex-direction: column (предполагая, что вы хотите, чтобы элементы укладывают друг на друга). Затем установите flex-grow: 1 на ребенка iframe элемент для того, чтобы заполнить оставшееся пространство.

    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 (первый метод работает во всех текущих броузеры.)


возможно, на это уже ответили (несколько ответов выше- "правильные" способы сделать это), но я подумал, что просто добавлю свое решение.

наш iFrame загружен в div, поэтому мне нужно было что-то еще, а затем окно.высота. И видя, что наш проект уже сильно зависит от jQuery, я считаю это самым элегантным решением:

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

где, конечно, "#middle " - это идентификатор div. Единственное, что вам нужно сделать, это вспомнить это изменение размера всякий раз, когда пользователь изменяет размер окна.

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

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;

вот что я сделал. У меня была такая же проблема, и я часами искал в интернете ресурсы.

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

Я добавил Это в раздел head.

обратите внимание, что мой iframe находится внутри средней ячейки таблицы, которая имеет 3 строки и 1 столбец.


попробуйте следующее:

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

это сработало для меня


вы можете сделать это с помощью 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>

правильно, вы показываете iframe со 100% высотой по отношению к его контейнеру: телу.

попробуйте это:

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

конечно, измените высоту второго div на нужную высоту.


новое в 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>

я использовал 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;
}

добавьте дополнительный div вокруг вашего iframe (или любой контент, который вам нужен) и сделайте его таблицей-строкой с высотой, установленной на 100% (установка ее высоты имеет решающее значение, если вы хотите встроить iframe для заполнения высоты)

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

Ниже приведен jsfiddle, показывающий его на работе (без iframe, потому что это, похоже, не работает в скрипке)

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


Я думаю, что у вас тут концептуальная проблема. Сказать "Я попытался установить высоту: 100% на iframe, результат довольно близок, но iframe попытался заполнить всю страницу", ну, когда "100% "не было равно"целому"?

вы попросили iframe заполнить всю высоту своего контейнера (который является телом), но, к сожалению, у него есть брат уровня блока в

, выше которого вы попросили быть 30px большим. Таким образом, родительский контейнер total теперь запрашивается размер до 100% + 30px > 100%! Следовательно, полосы прокрутки.

Что я думаю о тебе mean это то, что вы хотели бы, чтобы iframe потреблял то, что осталось как фреймы и ячейки таблицы могут, т. е. высота="*". IIRC этого не существует.

к сожалению, насколько мне известно, нет способа эффективно смешивать/вычислять / вычитать абсолютные и относительные единицы, поэтому я думаю, что вы сводитесь к двум вариантам:

  1. абсолютно позиционировать свой div, которые возьмет его из контейнера так только iframe будет потреблять его высота контейнеров. Это оставляет вас со всеми другими проблемами хотя, но, возможно, за то, что ты выполнение непрозрачности или выравнивания будет ладно.

  2. также необходимо указать % высота для div и уменьшает высота iframe на столько. Если абсолютная высота действительно это важно, вам нужно будет подать заявку что к дочернему элементу элемент div вместо.


попробовав 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


Он будет работать с указанным ниже кодом

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

аналогичный ответ @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


вы можете сделать это, измеряя размер тела при загрузке/изменении размера событий и установив высоту (полная высота - высота баннера).

обратите внимание, что в настоящее время в IE8 Beta2 вы не можете сделать это onresize, поскольку это событие в настоящее время нарушено в IE8 Beta2.


или вы можете пойти старой школы и использовать frameset возможно:

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

хотя я согласен, что JS кажется лучшим вариантом, у меня есть несколько CSS только рабочее решение. Недостатком этого является то, что если вам нужно часто добавлять контент в документ iframe html, вам придется адаптировать один процент времени.

устранение:

попробовать Не указан любая высота для обоих ваших html-документов,

html, body, section, main-div {}

тогда только этот код:

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

Примечание: div должен быть вашим главным раздел.

Это должно относительно работы. iframe точно вычисляет 300% высоты видимого окна. Если HTML-контент из 2-го документа (в iframe) меньше по высоте, чем в 3 раза выше Вашего браузера, он работает. Если вам не нужно часто добавлять контент в этот документ, это постоянное решение, и вы можете просто найти свой собственный%, необходимый в соответствии с высотой контента.

это работает, потому что он предотвращает 2-й html-документ (один embed)для наследования его высоты от родительского html-документа. Это предотвращает это, потому что мы не указали высоту для обоих из них. Когда мы даем % ребенку, он ищет своего родителя, если нет,он принимает высоту содержимого. И только если другим контейнерам не дают высоты, из того, что я пробовал.


в "бесшовные" атрибут-это новый стандарт, направленный на решение этой проблемы:

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

при назначении этого атрибута он удалит границы и полосы прокрутки и размер iframe до его размера содержимого. хотя он поддерживается только в Chrome и последнем Safari

подробнее об этом здесь: HTML5 iframe бесшовный атрибут


простое решение 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();
    }

}

вы не можете установить высоту iframe в%, Потому что высота вашего родительского тела не 100% , поэтому сделайте родительскую высоту 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>

Если у вас есть доступ к содержимому iframe, который будет загружен, вы можете сказать его родителю изменить размер при изменении размера..

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

Если у вас есть более одного iframe на странице, Вам может потребоваться использовать id или другие умные методы для улучшения .найдите ("iframe"), чтобы выбрать правильный вариант.


Я думаю, что лучший способ достичь этого сценария с помощью позиции css. установите положение относительно родительского div и положение: абсолютное для вашего 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 ()


почему бы не сделать это (с незначительной регулировкой для заполнения тела/полей)

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