Поддерживайте соотношение сторон div с помощью CSS


Я хочу создать div, который может изменять свою ширину / высоту по мере изменения ширины окна.

существуют ли какие-либо правила CSS3, которые позволили бы изменить высоту в соответствии с шириной,при сохранении его пропорций?

Я знаю, что могу сделать это с помощью JavaScript, но я бы предпочел использовать только CSS.

19 826

19 ответов:

просто создайте обертку <div> С процентным значением для padding-bottom, например:

div {
  width: 100%;
  padding-bottom: 75%;
  background: gold; /** <-- For the demo **/
}
<div></div>

это приведет к <div> С высотой, равной 75% ширины его контейнера (соотношение сторон 4:3).

это зависит от того, что для заполнения:

процент рассчитывается по отношению к ширина блока, содержащего сгенерированный блок [...] (источник: w3.org, акцент мой)

Padding-нижние значения для других соотношений сторон и 100% ширины:

aspect ratio  | padding-bottom value
--------------|----------------------
    16:9      |       56.25%
    4:3       |       75%
    3:2       |       66.66%
    8:5       |       62.5%

размещение контента в div :

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

div.stretchy-wrapper {
  position: relative;
}

div.stretchy-wrapper > div {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
}

здесь демо и еще один более глубокий демо

vw подразделения:

можно использовать vw для ширина и высота элемента. Это позволяет сохранить соотношение сторон элемента в зависимости от ширины видового экрана.

vw: 1/100th ширины видового экрана. [MDN]

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

пример: соотношение сторон 1:1

div {
  width: 20vw;
  height: 20vw;
  background: gold;
}
<div></div>

для других соотношений сторон вы можете использовать следующую таблицу для расчета значения высоты в соответствии с шириной элемента:

aspect ratio  |  multiply width by
-----------------------------------
     1:1      |         1
     1:3      |         3
     4:3      |        0.75
    16:9      |       0.5625

пример: 4x4 сетка квадратных дивов

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>

здесь возиться с этой демо и вот решение сделайте отзывчивая сетка квадратов с вертикальным и горизонтальным центрированным содержимым.


поддержка браузера для VH / vw единиц является IE9 + см canIuse для получения дополнительной информации

Я нашел способ сделать это с помощью CSS, но вы должны быть осторожны, так как это может измениться в зависимости от потока вашего собственного веб-сайта. Я сделал это для того, чтобы встроить видео с постоянным соотношением сторон в пределах жидкой части ширины моего веб-сайта.

скажем, у вас есть встроенный видео, как это:

<object>
     <param ... /><param ... />...
     <embed src="..." ...</embed>
</object>

затем вы можете поместить все это в div с классом "видео". Этот класс видео, вероятно, будет жидким элементом на вашем веб-сайте таким, что сам по себе он имеет нет прямых ограничений по высоте, но при изменении размера браузера он будет меняться по ширине в соответствии с потоком веб-сайта. Это будет элемент, который вы, вероятно, пытаетесь получить встроенное видео, сохраняя при этом определенное соотношение сторон видео.

для этого я помещаю изображение перед встроенным объектом в класс div "video".

!!! Важной частью является то, что изображение имеет правильное соотношение сторон, которое вы хотите сохранить. Также убедиться размер изображения, по крайней мере, такой же большой, как самый маленький, который вы ожидаете, что видео (или то, что вы поддерживаете A. R. of) будет основано на вашем макете. Это позволит избежать каких-либо потенциальных проблем в разрешении изображения при его процентном изменении. Например, если вы хотите сохранить соотношение сторон 3:2, не просто используйте изображение 3px на 2px. Он может работать при некоторых обстоятельствах, но я его не тестировал, и, вероятно, было бы неплохо избежать.

вы должны вероятно, уже есть минимальная ширина, как это определено для жидких элементов вашего веб-сайта. Если нет, то это хорошая идея, чтобы сделать это, чтобы избежать отсечения элементов или перекрытия, когда окно браузера становится слишком маленьким. Лучше иметь полосу прокрутки в какой-то момент. Самая маленькая по ширине веб-страница должна быть где-то около ~600px (включая любые столбцы фиксированной ширины), потому что разрешения экрана не уменьшаются, если вы не имеете дело с удобными для телефона сайтами. !!!

Я использую полностью прозрачный png, но я действительно не думаю, что это имеет значение, если вы сделаете это правильно. Вот так:

<div class="video">
     <img class="maintainaspectratio" src="maintainaspectratio.png" />
     <object>
          <param ... /><param ... />...
          <embed src="..." ...</embed>
     </object>
</div>

Теперь вы должны быть в состоянии добавить CSS, подобный следующему:

div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }

убедитесь, что вы также удаляете любое явное объявление высоты или ширины в объекте и вставляете теги, которые обычно поставляются с копией/вставкой кода вставки.

способ его работы зависит от свойств позиции элемента класса видео и элемент, который вы хотите поддерживать определенное соотношение сторон. Он использует то, как изображение будет поддерживать свое правильное соотношение сторон при изменении размера в элементе. Он говорит, что все остальное находится в элементе видео класса, чтобы в полной мере воспользоваться недвижимостью, предоставляемой динамическим изображением, заставляя его ширину/высоту до 100% элемента видео класса, регулируемого изображением.

круто, да?

возможно, Вам придется немного поиграть с ним, чтобы заставить его работать с вашим собственный дизайн, но это на самом деле работает на удивление хорошо для меня. Общая концепция есть.

чтобы добавить к ответу Web_Designer,<div> будет иметь высоту (полностью состоит из нижней прокладки) 75% от ширины его содержит элемент. Вот хорошее резюме:http://mattsnider.com/css-using-percent-for-margin-and-padding/. я не уверен, почему это должно быть так, но так оно и есть.

Если вы хотите, чтобы ваш div был шириной, отличной от 100%, вам нужен другой обертывающий div, на котором можно установить ширину:

div.ar-outer{
    width: 60%; /* container; whatever width you want */
    margin: 0 auto; /* centered if you like */
}
div.ar {
    width:100%; /* 100% of width of container */
    padding-bottom: 75%; /* 75% of width of container */
    position:relative;
}
div.ar-inner {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

Я что-то похожее на трюк изображения Эллиота недавно, чтобы позволить мне использовать css media queries для обслуживания другого файла логотипа в зависимости от разрешения устройства, но все же пропорционально масштабируется как <img> естественно, сделал бы (я установил логотип в качестве фонового изображения на прозрачный .png с правильным соотношением сторон). Но решение Web_Designer сэкономит мне http-запрос.

Эллиот вдохновил меня на это решение-спасибо:

aspectratio.png это полностью прозрачный PNG-файл с размером вашего предпочтительного соотношения сторон, в моем случае 30x10 пикселей.

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

обратите внимание:background-size это css3-функция, которая может не работать с вашими целевыми браузерами. Вы можете проверить совместимость (например, на caniuse.com).

Как говорится в здесь дальше w3schools.com и несколько повторил в этом принято отвечать, значения заполнения в процентах (акцент мой):

задает отступ в процентах от ширины содержит элемент

Ergo, правильный пример отзывчивого DIV, который сохраняет соотношение сторон 16: 9, выглядит следующим образом следует:

CSS

.parent {
    position: relative;
    width: 100%;
}
.child {
    position: relative;
    padding-bottom: calc(100% * 9 / 16);
}
.child > div {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

HTML

<div class="parent">
    <div class="child">
        <div>Aspect is kept when resizing</div>
    </div>
</div>

демо на JSFiddle

основываясь на ваших решениях я сделал некоторые трюки:

когда вы используете его, ваш HTML будет только

<div data-keep-ratio="75%">
    <div>Main content</div>
</div>

чтобы использовать его таким образом сделать: CSS:

*[data-keep-ratio] {
    display: block;
    width: 100%;
    position: relative;
}
*[data-keep-ratio] > * {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

и js (jQuery)

$('*[data-keep-ratio]').each(function(){ 
    var ratio = $(this).data('keep-ratio');
    $(this).css('padding-bottom', ratio);
});

и имея это вы просто установите attr data-keep-ratio к высоте / ширине и это все.

вы можете использовать svg. Сделайте положение контейнера / обертки относительным, поместите svg сначала как статически расположенное, а затем поместите абсолютно расположенное содержимое (сверху: 0; слева:0; справа:0; снизу:0;)

пример с пропорциями 16: 9:

изображения.svg: (может быть встроен в src)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

обратите внимание, что встроенный svg, похоже, не работает, но вы можете urlencode svg и встроить его в атрибут img src вот так:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />

как @web-tiki уже показывают способ использования vh/vw, мне также нужен способ центрироваться на экране, вот фрагмент кода для 9:16 портрет.

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateY будет держать этот центр на экране. calc(100vw * 16 / 9) ожидается рост на 9/16.(100vw * 16 / 9 - 100vh) это высота переполнения, так что, потяните вверх overflow height/2 будет держать его в центре экрана.

для ландшафта, и сохранить 16:9, вы показываете использовать

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

коэффициент 9/16 легкость чтобы изменить, не нужно предопределено 100:56.25 или 100:75.Если вы хотите сначала обеспечить высоту, вы должны переключить ширину и высоту, например height:100vh;width: calc(100vh * 9 / 16) для портрета 9:16.

если вы хотите адаптироваться для разных размеров экрана, вы также можете заинтересовать

  • фон-в размере крышка/содержать
    • выше стиль похож на содержать, зависит от ширины: высота соотношение.
  • object-fit
    • обложка / содержит для тега img / video
  • @media (orientation: portrait)/@media (orientation: landscape)
    • запрос медиа portrait/landscape изменить соотношение.

SCSS является лучшим решением в моем случае; с помощью атрибута данных:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;

    &:before {
        content: '';
        display: block;
    }

    > * {
        display: block;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

например :

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

источник

допустим, у вас есть 2 divs outher div-это контейнер, а внутренний может быть любым элементом, который вам нужно сохранить его соотношение (img или iframe youtube или что-то еще )

html выглядит так:

<div class='container'>
  <div class='element'>
  </div><!-- end of element -->

допустим, вам нужно сохранить соотношение "элемент"

отношение = > 4 к 1 или 2 к 1 ...

css выглядит так

.container{
  position: relative;
  height: 0
  padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/

}

.element{
  width : 100%;
  height: 100%;
  position: absolute; 
  top : 0 ;
  bottom : 0 ;
  background : red; /* just for illustration */
}

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

просто идея или взломать.

div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>

я столкнулся с этой проблемой довольно много раз, поэтому я сделал JS-решение для нее. Это в основном регулирует высоту купола в соответствии с шириной элемента по указанному вами соотношению. Вы можете использовать его следующим образом:

<div ratio="4x3"></div>

обратите внимание, что поскольку он устанавливает высоту элемента, элемент должен быть либо display:block или display:inline-block.

https://github.com/JeffreyArts/html-ratio-component

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

Я попытался соединить их вместе, чтобы получить полностью портативное и значительное решение... Трюк состоит в том, чтобы использовать для автоматического масштабирования изображения, но использовать встроенный элемент svg вместо использования предварительно отрисованного изображения или любой формы второго запрос http...

div.holder{
  background-color:red;
  display:inline-block;
  height:100px;
  width:400px;
}
svg, img{
  background-color:blue;
  display:block;
  height:auto;
  width:auto;
  max-width:100%;
  max-height:100%;
}
.content_sizer{
  position:relative;
  display:inline-block;
  height:100%;
}
.content{
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  background-color:rgba(155,255,0,0.5);
}
<div class="holder">
  <div class="content_sizer">
    <svg width=10000 height=5000 />
    <div class="content">
    </div>
  </div>
</div>

обратите внимание, что я использовал большие значения в атрибутах ширины и высоты SVG, так как он должен быть больше, чем максимальный ожидаемый размер, поскольку он может только сжиматься. Пример делает отношение div 10: 5

если вы хотите разместить квадрат внутри окна просмотра на портретном или ландшафтном виде (как можно больше, но ничего не торчит снаружи), переключайтесь между использованием vw/vh на направлении portrait/landscape:

@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 

это улучшение по сравнению с принятым ответом:

  • использует псевдо элементы вместо обертки divs
  • соотношение сторон основано на ширине коробки вместо ее родительского
  • коробка будет растягиваться вертикально, когда содержимое становится выше

.box {
  margin-top: 1em;
  margin-bottom: 1em;
  background-color: #CCC;
}

.fixed-ar::before {
  content: "";
  float: left;
  width: 1px;
  margin-left: -1px;
}
.fixed-ar::after {
  content: "";
  display: table;
  clear: both;
}

.fixed-ar-16-9::before {
  padding-top: 56.25%;
}
.fixed-ar-3-2::before {
  padding-top: 66.66%;
}
.fixed-ar-4-3::before {
  padding-top: 75%;
}
.fixed-ar-1-1::before {
  padding-top: 100%;
}

.width-50 {
  display: inline-block;
  width: 50%;
}
.width-20 {
  display: inline-block;
  width: 20%;
}
<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div>
<div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div>
<div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>

вы можете использовать макет потока (FWD).

https://en.wikipedia.org/wiki/Adaptive_web_design

Он будет масштабироваться и поддерживать макет, его немного сложный, но позволяет изменять размер страницы, не нажимая на контент, например (RWD).

Это выглядит как отзывчивый, но это масштабирование. https://www.youtube.com/watch?v=xRcBMLI4jbg

вы можете найти формулу масштабирования CSS здесь:

http://plugnedit.com/pnew/928-2/

Если бы вся структура контейнера была основана на процентах, это было бы поведение по умолчанию, вы можете предоставить более конкретный пример?

Ниже приведен пример того, что я имею в виду, если вся ваша родительская иерархия была основана на%, любая настройка окна браузера будет работать без каких-либо дополнительных js/css, разве это не возможно с вашим макетом?

<div style="width: 100%;">
   <div style="width: 50%; margin: 0 auto;">Content</div>
</div>

я использовал новое решение.

.squares{
  width: 30vw
  height: 30vw

к основному соотношению сторон

.aspect-ratio
  width: 10vw
  height: 10vh

однако, это относительно всего просмотра. Таким образом, если вам нужен div, который составляет 30% от ширины видового экрана, вы можете использовать 30vw вместо этого, и поскольку вы знаете ширину, вы повторно используете их по высоте с помощью calc и vw unit.