Я пытаюсь использовать единицы CSS vh
внутри iframe. Я обнаружил, что они каким-то образом масштабируются до размера iframe. Другими словами, 100vh не является окном. Он установлен на высоту iframe.
Правильно ли это?
Есть ли способ обхода?
Я пытаюсь использовать единицы CSS vh
внутри iframe. Я обнаружил, что они каким-то образом масштабируются до размера iframe. Другими словами, 100vh не является окном. Он установлен на высоту iframe.
Правильно ли это?
Есть ли способ обхода?
Я знаю, что это старый вопрос, но по мере продвижения людей к vh
подразделению этот вопрос станет гораздо более распространенным.
Чтобы уточнить, вот пример проблемы. У нас есть HTML файл, который загружает iframe
:
<!DOCTYPE html>
<html>
<head></head>
<style>
iframe {
height: 50vh;
width: 100%;
}
</style>
<body>
<iframe src="iframe.html"/>
</body>
</html>
И его iframe
:
<!DOCTYPE html>
<html>
<head></head>
<style>
div {
height: 50vh;
width: 100%;
background: blue;
}
</style>
<body>
<div></div>
</body>
</html>
Здесь важно отметить, что и iframe
и div
элемент iframe's
имеют высоту 50vh
. Предполагаемое поведение может заключаться в том, что iframe
учитывает высоту или ширину области просмотра родительского контекста. Вместо этого результат выглядит так:
То есть высота синего элемента составляет ~ 25% от окна браузера, вместо ожидаемых 50% (100% от iframe
). Хотя мы можем пожелать, чтобы iframe
уважал область просмотра своего родителя, этот пример хорошо иллюстрирует, насколько это может быть не интуитивно понятно, хотя, безусловно, это сделает единицы v*
более ценными для содержания, в котором находится iframe
. Проблема заключается в том, что делать с тем, как определяется высота области просмотра.
Из спецификации:
Длина области просмотра в процентах относится к размеру исходного содержащего блока. Когда высота или ширина исходного содержащего блока изменяется, они масштабируются соответственно.
И iframe
и окно браузера могут быть начальным содержащим блоком, поскольку они оба являются действительными окнами просмотра. Окно просмотра не ограничивается окном браузера, а определяется как окно или другая область просмотра на экране, через которую пользователи обращаются к документу.
При вставке в документ iframe
создает вложенный контекст просмотра и, таким образом, имеет собственный видовой экран.
Так что да, это предполагаемое поведение - и, к сожалению, нет чистого обходного пути CSS - однако, www139 предоставил пример того, как это можно сделать с помощью JavaScript. Проблема с этим начинается, когда размер многих элементов контролируется с помощью единиц v*
.
Это отличный вопрос. К сожалению, мне не удалось найти решение в CSS, но я смог найти решение в JavaScript, которое я считаю вашим лучшим выбором на данный момент. Помните, что фреймы должны быть в одном домене, чтобы это работало.
Надеюсь это поможет. Если этот ответ нуждается в улучшении, пожалуйста, прокомментируйте ниже :-)
Решение в теории (не может использоваться здесь на SO из-за проблемы происхождения фрейма):
window.addEventListener('load',function(){
initializeV();
function initializeV(){
//1% of the parent viewport width (same as 1vw):
var vw = window.parent.innerWidth/100;
//1% of the viewport height (same as 1vh):
var vh = window.parent.innerHeight/100;
//assign width and height to your v unit elements here
}
window.parent.addEventListener('resize',function(){
//when the browser window is resized; recalculate
initializeV();
});
});
Изменить (декабрь 2018): В комментариях меня попросили привести пример. Я не могу сделать точный пример, потому что codepens на Stackoverflow загружают по другому источнику кадра, чем страница. Тем не менее, я могу имитировать эффект. Для практического применения, пожалуйста, обратитесь к фрагменту кода выше. Этот фрагмент предназначен только для иллюстрации того, как он работает.
Практическое применение. Использует концепцию, объясненную выше, но без ссылки на кадр.
window.addEventListener('load',function(){
initializeV();
function initializeV(){
//note: I can't use window.parent becuase the code snippet loads on a different frame than the parent page. See the other snippet for a practical example. This snippet is meant to merely illustrate the effect.
//1% of the parent viewport width (same as 1vw):
var vw = window.innerWidth/100;
//1% of the viewport height (same as 1vh):
var vh = window.innerHeight/100;
//this is where the magic happens. Simply set width/height/whatever to a multiple of vw/vh and add 'px'. Dimensions must be in pixels since the vw/vh measurement is based on pixels.
document.getElementById('test').style.width = 30*vw+'px';
document.getElementById('test').style.height = 50*vh+'px';
//assign width and height to your v unit elements here
}
window.addEventListener('resize',function(){
//when the browser window is resized; recalculate
initializeV();
});
});
#test{
background:red;
}
<div id="test"></div>