Поддерживайте соотношение сторон div, но заполняйте ширину и высоту экрана в CSS?
у меня есть сайт, чтобы собрать, что имеет фиксированное соотношение сторон примерно 16:9 пейзаж, как видео.
Я хочу, чтобы он центрировался и расширялся, чтобы заполнить доступную ширину и доступную высоту, но никогда не увеличивался с обеих сторон.
например:
- высокая и тонкая страница будет иметь содержимое, растягивающееся на всю ширину при сохранении пропорциональной высоты.
- короткая широкая страница будет иметь содержание, растягивающееся на всю высоту, с пропорциональной шириной.
есть два метода, которые я рассматривал:
- используйте изображение с правильным соотношением сторон, чтобы развернуть контейнер
div, но я не мог заставить его вести себя одинаково во всех основных браузерах. - установка пропорционального Нижнего заполнения, но это работает только относительно ширины и игнорирует высоту. Он просто продолжает становиться больше с шириной и отображает вертикальные полосы прокрутки.
Я знаю, что вы могли бы сделать это с JS довольно легко, но я хотел бы чистое решение CSS.
какие идеи?
7 ответов:
использовать новый CSS viewport units
vwиvh(ширина видового экрана / высота видового экрана)измените размер по вертикали и горизонтали, и вы увидите, что элемент всегда будет заполнять максимальный размер видового экрана, не нарушая соотношение и без полос прокрутки!
(ЧИСТЫЙ) 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>если вы хотите использовать максимум скажем 90% ширины и высоты видового экрана:скрипка
* { margin: 0; padding: 0; } div { width: 90vw; /* 90% of viewport vidth */ height: 50.625vw; /* ratio = 9/16 * 90 = 50.625 */ background: pink; max-height: 90vh; max-width: 160vh; /* 16/9 * 90 = 160 */ margin: auto; position: absolute; top: 0; bottom: 0; left: 0; right: 0; }<div></div>кроме того, поддержка браузера тоже довольно хороша: IE9+, FF, Chrome, Safari -caniuse
просто переформулировать
Danield' s ответ в меньшем 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; }
мой первоначальный вопрос для этого состоял в том, как иметь элемент фиксированного аспекта, но точно вписать его в указанный контейнер, что делает его немного неудобным. Если вы просто хотите, чтобы отдельный элемент поддерживал свое соотношение сторон, это намного проще.
лучший метод, с которым я столкнулся,-это дать элементу нулевую высоту, а затем использовать процентное заполнение-дно, чтобы дать ему высоту. Процент заполнения всегда пропорционален ширине элемента, а не его высота, даже если ее верхняя или нижняя обивка.
таким образом, используя, что вы можете дать элементу процентную ширину, чтобы сидеть в контейнере, а затем заполнить, чтобы указать соотношение сторон или, другими словами, отношение между его шириной и высотой.
.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.
использовать CSS media query
@mediaвместе с CSS viewport unitsvwи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подход by @Danield, просто более гибкий.
Я понимаю, что вы спросили, что вы хотели бы
CSSконкретное решение. Чтобы сохранить соотношение сторон, вам нужно будет разделить высоту на желаемое соотношение сторон. 16:9 = 1.777777777778.чтобы получить правильную высоту для контейнера, вам нужно будет разделить текущую ширину на 1.777777777778. Так как вы не можете проверить
widthиз контейнера только сCSSили разделить на процент этоCSS, это невозможно безJavaScript(к моему знание.)я написал рабочий скрипт, который будет сохранять нужные пропорции.
HTML
<div id="aspectRatio"></div>CSS
body { width: 100%; height: 100%; padding: 0; margin: 0; } #aspectRatio { background: #ff6a00; }JavaScript
window.onload = function () { //Let's 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);
теперь для этого задано новое свойство CSS:
object-fit.http://docs.webplatform.org/wiki/css/properties/object-fit
поддержка браузера все еще несколько отсутствует (http://caniuse.com/#feat=object-fit) - в настоящее время работает в некоторой степени в большинстве браузеров, кроме Microsoft - но с учетом времени это именно то, что требовалось для этого вопроса.
ответ Данилда это хорошо, но он может быть использован только тогда, когда 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>вот он в jsfiddle с помощью scss, что делает его более очевидным, откуда берутся значения.