Поддерживать соотношение сторон div, но ширину и высоту экрана в CSS?
У меня есть сайт для сборки, который имеет фиксированное соотношение сторон приблизительно 16:9
ландшафта, например видео.
Я хочу, чтобы он был центрирован и расширялся, чтобы заполнить доступную ширину и доступную высоту, но никогда не увеличиваться с обеих сторон.
Например:
- Высокая и тонкая страница будет иметь контент, растягивающий всю ширину, сохраняя пропорциональную высоту.
- У короткой широкой страницы будет содержание, растянутое на всю высоту с пропорциональной шириной.
Есть два метода, на которые я смотрел:
- Используйте изображение с правильным соотношением сторон, чтобы развернуть контейнер
div
, но я не мог заставить его вести себя одинаково в основных браузерах.
- Установка пропорционального нижнего заполнения, но это работает только относительно ширины и игнорирует высоту. Он просто увеличивается с шириной и отображает вертикальные полосы прокрутки.
Я знаю, что вы можете сделать это с JS довольно легко, но я бы хотел получить чистое решение CSS.
Любые идеи?
Ответы
Ответ 1
Теперь для этого используется новый CSS-свойство: object-fit
.
http://docs.webplatform.org/wiki/css/properties/object-fit
Поддержка браузеров по-прежнему несколько отсутствует (http://caniuse.com/#feat=object-fit) - в настоящее время работает в некоторой степени в большинстве браузеров, кроме Microsoft, но с учетом времени именно то, что требовалось для этого вопроса.
Ответ 2
Используйте новые узлы просмотра CSS vw
и vh
(ширина видового экрана/высота видового экрана)
FIDDLE
Измените размер по вертикали и по горизонтали, и вы увидите, что элемент всегда будет заполнять максимальный размер видового экрана без нарушения отношения и без полос прокрутки!
(PURE) CSS
div
{
width: 100vw;
height: 56.25vw; /* height:width ratio = 9/16 = .5625 */
background: pink;
max-height: 100vh;
max-width: 177.78vh; /* 16/9 = 1.778 */
margin: auto;
position: absolute;
top:0;bottom:0; /* vertical center */
left:0;right:0; /* horizontal center */
}
* {
margin: 0;
padding: 0;
}
div {
width: 100vw;
height: 56.25vw;
/* 100/56.25 = 1.778 */
background: pink;
max-height: 100vh;
max-width: 177.78vh;
/* 16/9 = 1.778 */
margin: auto;
position: absolute;
top: 0;
bottom: 0;
/* vertical center */
left: 0;
right: 0;
/* horizontal center */
}
<div></div>
Ответ 3
Просто переформулировав Danield
ответ в LESS mixin, для дальнейшего использования:
// Mixin for ratio dimensions
.viewportRatio(@x, @y) {
width: 100vw;
height: @y * 100vw / @x;
max-width: @x / @y * 100vh;
max-height: 100vh;
}
div {
// Force a ratio of 5:1 for all <div>
.viewportRatio(5, 1);
background-color: blue;
margin: 0;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
Ответ 4
Мой оригинальный вопрос для этого состоял в том, как обе имеют элемент фиксированного аспекта, но точно соответствуют этому в определенном контейнере, что делает его немного затруднительным. Если вы просто хотите, чтобы отдельный элемент поддерживал соотношение сторон, это намного проще.
Лучший метод, с которым я столкнулся, - это указать нулевую высоту элемента, а затем использовать процентное заполнение-снизу, чтобы дать ему высоту. Процент заполнения всегда пропорционален ширине элемента, а не его высоте, даже если его верхняя или нижняя прокладка.
Свойства W3C Padding
Таким образом, используя это, вы можете дать элементу процентную ширину для размещения внутри контейнера, а затем отложить, чтобы указать соотношение сторон или, другими словами, соотношение между его шириной и высотой.
.object {
width: 80%; /* whatever width here, can be fixed no of pixels etc. */
height: 0px;
padding-bottom: 56.25%;
}
.object .content {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
padding: 40px;
}
Итак, в приведенном выше примере объект занимает 80% от ширины контейнера, а затем его высота составляет 56,25% от этого значения. Если ширина равна 160px, то нижняя прокладка, и, следовательно, высота будет 90px - аспект 16: 9.
Небольшая проблема здесь, которая может не быть проблемой для вас, заключается в том, что в вашем новом объекте нет естественного пространства. Если вам нужно поместить некоторый текст, например, и чтобы текст должен был иметь собственные значения заполнения, вам нужно добавить контейнер внутри и указать там свойства.
Кроме того, vw и vh не поддерживаются в некоторых старых браузерах, поэтому принятый ответ на мой вопрос может оказаться невозможным для вас, и вам, возможно, придется использовать что-то еще lo-fi.
Ответ 5
Используйте мультимедийный запрос CSS @media
вместе с CSS видовых экранов vw
и vh
для адаптации к пропорциям видового экрана. Это полезно для обновления других свойств, таких как font-size
.
Эта скрипта демонстрирует фиксированное соотношение сторон для div и текст, соответствующий его масштабу точно.
Исходный размер основан на полной ширине:
div {
width: 100vw;
height: calc(100vw * 9 / 16);
font-size: 10vw;
/* align center */
margin: auto;
position: absolute;
top: 0px; right: 0px; bottom: 0px; left: 0px;
/* visual indicators */
background:
url(data:image/gif;base64,R0lGODlhAgAUAIABAB1ziv///yH5BAEAAAEALAAAAAACABQAAAIHhI+pa+EPCwA7) repeat-y center top,
url(data:image/gif;base64,R0lGODlhFAACAIABAIodZP///yH5BAEAAAEALAAAAAAUAAIAAAIIhI8Zu+nIVgEAOw==) repeat-x left center,
silver;
}
Затем, когда область просмотра более широкая, чем желаемое соотношение сторон, переключитесь на высоту в качестве базовой меры:
/* 100 * 16/9 = 177.778 */
@media (min-width: 177.778vh) {
div {
height: 100vh;
width: calc(100vh * 16 / 9);
font-size: calc(10vh * 16 / 9);
}
}
Это очень похоже в вене с max-width
и max-height
подход от @Danield, более гибкий.
Ответ 6
Я понимаю, что вы спросили, что вам нужно специальное решение CSS
. Чтобы сохранить соотношение сторон, вам необходимо разделить высоту на желаемое соотношение сторон. 16: 9 = 1,777777777778.
Чтобы получить правильную высоту для контейнера, вам нужно будет разделить текущую ширину на 1.777777777778. Поскольку вы не можете проверить width
контейнера только с CSS
или делить на процент CSS
, это невозможно без JavaScript
(насколько мне известно).
Я написал рабочий script, который сохранит желаемое соотношение сторон.
HTML
<div id="aspectRatio"></div>
CSS
body { width: 100%; height: 100%; padding: 0; margin: 0; }
#aspectRatio { background: #ff6a00; }
JavaScript
window.onload = function () {
//Let create a function that will scale an element with the desired ratio
//Specify the element id, desired width, and height
function keepAspectRatio(id, width, height) {
var aspectRatioDiv = document.getElementById(id);
aspectRatioDiv.style.width = window.innerWidth;
aspectRatioDiv.style.height = (window.innerWidth / (width / height)) + "px";
}
//run the function when the window loads
keepAspectRatio("aspectRatio", 16, 9);
//run the function every time the window is resized
window.onresize = function (event) {
keepAspectRatio("aspectRatio", 16, 9);
}
}
Вы можете снова использовать function
, если вы хотите отобразить что-то другое с другим соотношением, используя
keepAspectRatio(id, width, height);
Ответ 7
ответ Danield хорош, но его можно использовать только тогда, когда div заполняет весь видовой экран, или используя бит calc
, можно использовать, если ширина и высота другого содержимого в окне просмотра.
Однако, объединив трюк margin-bottom
с методом в вышеупомянутом ответе, проблему можно свести к тому, чтобы знать высоту другого содержимого. Это полезно, если у вас есть фиксированный заголовок высоты, но ширина боковой панели, например, неизвестна.
body {
margin: 0;
margin-top: 100px; /* simulating a header */
}
main {
margin: 0 auto;
max-width: calc(200vh - 200px);
}
section {
padding-bottom: 50%;
position: relative;
}
div {
position:absolute;
background-color: red;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
<main>
<section>
<div></div>
</section>
</main>