Как сохранить соотношение сторон у блока css
От автора: в этой статье мы поговорим о том, как соотнести стороны в CSS. Ранее мы рассмотрели Соотношение сторон блоков. В том числе, как с помощью отступов сделать так, чтобы элемент имел нужное вам соотношение сторон. Потребность в использовании этого метода возникает не часто, поскольку это связано с некоторыми трудностями. Но время от времени нам все же бывает нужно сделать это.
Одним из возможных вариантов использования данного метода является Применение псевдо-элементов, когда этот псевдо элемент задает соотношение сторон родительского элемента. Но если для размещения содержимого нужна большая высота, высота блока растягивается, и соотношение сторон нарушается.
Вы можете использовать этот прием для сеток CSS с элементами grid! Есть несколько возможных способов применения данного метода.
Области сетки и элементы, которые для них назначены, не обязательно должны иметь одинаковые размеры
Недавно мы рассматривали данную тему. Та статья задумывалась как вступление для данной, однако рассматриваемая в ней тема была достаточно важной, чтобы вынести ее отдельно.
Помня об этом, мы можем решить, что нам нужна область сетки, а также элемент, который будет растягиваться на всю ее высоту и ширину. Или нам просто нужно задать для элемента соотношение сторон независимо от области сетки для которой он назначен?
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Сценарий 2. Размещение нескольких столбцов необходимой ширины
Готов побиться об заклад, скорее всего, то, что вам нужно — это возможность создать несколько элементов, соотношение ширины которых будет составлять, например, 2 к 1. То есть фактически один элемент разбить на два столбца. Это очень похоже на то, что мы только что сделали, только здесь еще добавляются правила для создания этих столбцов.
Если мы еще добавим grid-auto-flow: dense;, то получим элементы с различными пропорциями, которые красиво укладываются.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Сейчас самое подходящее время привести несколько простых приемов, которые позволяют точно определить пропорции. line-height для определенного текста может растянуть блок выше, чем вам нужно. Если вы использкете grid-gap, это может привести к нарушению пропорций. Если вам нужно сверхточно задать соотношение сторон в соответствии с коэффициентом, вы можете сделать это жестко задав соотношение через код.
Определение ширины столбцов также становится труднее выполнить, если мы имеем дело с сеткой, у которой нет заданного количества строк. Возможно, у вас может использоваться повтор / автозаполнение. Вы можете столкнуться с ситуацией, когда столбцы будут иметь различную ширину в разных строках. И это также создает трудности с указанием соотношения сторон. Возможно, мы рассмотрим этот сценарий в другое время.
IE7 и ниже
37 Answers 37
Just create a wrapper with a percentage value for padding-bottom , like this:
It will result in a with height equal to 75% of the width of its container (a 4:3 aspect ratio).
This relies on the fact that for padding :
Padding-bottom values for other aspect ratios and 100% width :
Placing content in the div :
In order to keep the aspect ratio of the div and prevent its content from stretching it, you need to add an absolutely positioned child and stretch it to the edges of the wrapper with:
@schellmax, it is because padding % is calculated relative to the current element's width, where as height % is calculated relative to the parent element's height. Furthermore, absolute positions are calculated relative to the outside container of an element, which includes the padding area. For more information Google "CSS Box Model"
This does not seem to work in a nested fashion. It works at the first level, but when trying to do the same thing inside of the div maintaining aspect ratio, the padding-bottom percentage seems to get applied to the width of the parent. here is an example where the .stretchy-wrap.onethird padding-bottom of 25% is actually 25% of the parent width. Can someone explain this?
If you can't use aspect-ratio from 2021, here is an alternative solution: codepen.io/bagermen/pen/rNzOxMQ
There are several ways to specify a fixed aspect ratio on an element like a div, here are 2 of them:
This is the most simple and flexible solution. It directly specifies a fixed width to height (or height to width) aspect ratio for an element. This means you can also specify an aspect ratio according to the elements height.
It doesn't rely on the parent width (like the padding technique) or the viewport size (like the following vw unit technique) it relies on the element's own width or height More info on MDN. That is what make it so powerfull compared to other workarounds.
This is a modern property (2021). All modern browsers support it, see caniuse for precise browser support.
Here are a few examples with different aspect ratios :
You can use vw units for both the width and height of the element. This allows the element's aspect ratio to be preserved, based on the viewport width.
Alternatively, you can also use vh for viewport height, or even vmin / vmax to use the lesser/greater of the viewport dimensions (discussion here).
Example: 1:1 aspect ratio
For other aspect ratios, you can use the following table to calculate the value for height according to the width of the element :
Введение: Что такое соотношение сторон?
Согласно Википедии: В математике соотношение указывает, сколько раз одно число содержит другое. Например, если в миске с фруктами находится восемь апельсинов и шесть лимонов, то соотношение апельсинов и лимонов будет восемь к шести (то есть 8∶6, что эквивалентно соотношению 4∶3).
В веб-дизайне понятие соотношения сторон используется для описания того, что ширина и высота изображения должны изменяться пропорционально друг другу. Рассмотрим следующий рисунок.
У нас соотношение 4: 3. Это показывает, что соотношение яблока и винограда составляет четыре к трем. Другими словами, самый маленький прямоугольник, который мы можем создать для соотношения сторон 4: 3, — это прямоугольник 4 * 3 пикселя. Когда высота этого блока изменяется пропорционально его ширине, у нас будет блок, который соблюдает соотношение сторон. Рассмотрим следующий рисунок.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Размер поля изменяется пропорционально, и соотношение между его шириной и высотой остается неизменным. Теперь представим, что коробка содержит важное изображение, и мы заботимся обо всех его деталях.
Обратите внимание, что детали изображения сохраняются независимо от размера. Имея постоянное соотношение сторон, мы можем получить следующие преимущества:
Изображения на веб-сайте будут одинаковыми для разных размеров области просмотра.
Важные детали сохранены.
У нас тоже могут быть отзывчивые видеоэлементы.
Это помогает дизайнерам создавать четкое руководство по размеру изображений, чтобы разработчики могли обрабатывать их в процессе разработки.
Example: 4x4 grid of square divs
Browser support for vh/vw units is IE9+ see canIuse for more info
Note: When you only use the width property with 100% as value, this width will be calculated, so that it won't fill the horizontal space. When you want to preserve the 100% width, you have to add both width and height with each 100% set. That way it will work (at least in the latest Chrome it works correctly).
I stumbled upon what I consider a smart solution for this problem, using and display:grid .
A display:grid element allows you to occupy the same space with two (or more) of its children, using the same grid-area .
This means means they are all flow content, overlapped, and out of the box the taller one sets the ratio.
One of them will be an in charge of setting the ratio. The other, actual content. If actual content is short and never fills up the entire ratio (and you just want it centered in a space with this ratio), simply center it (see first runnable snippet below).
Set s ratio to whatever you want:
If you need a solution where the content element has more content you want confined into a scrollable area with desired ratio, set position:relative on the parent and position:absolute; height:100%; overflow-y: auto; on the content, allowing the flow content element (the ) to set the size, therefore the ratio.
As @emjay noted in a comment below, the ratio svg can be placed in one of the parent's pseudo-elements, as long as it's properly encoded:
When used inside a pseudo-element, the becomes a replaced element which, by default, sits on a baseline of variable height ( 4px in Chrome, 3.5px in Firefox). The height of the baseline varies according to line-height , which is why we need to set line-height: 0 on the pseudo to get an accurate ratio. More details here.
I personally prefer the version where the is placed in markup, as I can have a single class ( .ratio ) dealing with containers of various ratios (as opposed to having a class for each individual ratio I might need).
I've found a way to do this using CSS, but you have to be careful as it may change depending on the flow of your own web site. I've done it in order to embed video with a constant aspect ratio within a fluid width portion of my web site.
Say you have an embedded video like this:
You could then place this all inside a div with a "video" class. This video class will probably be the fluid element in your website such that, by itself, it has no direct height constraints, but when you resize the browser it will change in width according to the flow of the web site. This would be the element you are probably trying to get your embedded video in while maintaining a certain aspect ratio of the video.
In order to do this, I put an image before the embedded object within the "video" class div.
. The important part is that the image has the correct aspect ratio you wish to maintain. Also, make sure the size of the image is AT LEAST as big as the smallest you expect the video (or whatever you are maintaining the A.R. of) to get based on your layout. This will avoid any potential issues in the resolution of the image when it is percentage-resized. For example, if you wanted to maintain an aspect ratio of 3:2, don't just use a 3px by 2px image. It may work under some circumstances, but I haven't tested it, and it would probably be a good idea to avoid.
You should probably already have a minimum width like this defined for fluid elements of your web site. If not, it is a good idea to do so in order to avoid chopping elements off or having overlap when the browser window gets too small. It is better to have a scroll bar at some point. The smallest in width a web page should get is somewhere around ~600px (including any fixed width columns) because screen resolutions don't come smaller unless you are dealing with phone-friendly sites. .
I use a completely transparent png but I don't really think it ends up mattering if you do it right. Like this:
Now you should be able to add CSS similar to the following:
Make sure you also remove any explicit height or width declaration within the object and embed tags that usually come with copy/pasted embed code.
The way it works depends on the position properties of the video class element and the item you want have maintain a certain aspect ratio. It takes advantage of the way an image will maintain its proper aspect ratio when resized in an element. It tells whatever else is in video class element to take full-advantage of the real estate provided by the dynamic image by forcing its width/height to 100% of the video class element being adjusted by the image.
You might have to play around with it a bit to get it to work with your own design, but this actually works surprisingly well for me. The general concept is there.
От автора: важно иметь постоянное соотношение ширины и высоты изображений и других адаптивных элементов. В CSS мы много лет использовали метод заполнения отступов, но теперь у нас есть встроенная поддержка соотношения сторон в CSS. В этой статье я расскажу, что такое соотношение сторон, как мы это делали и как это сделать по-новому. Конечно, будут примеры с соответствующими вариантами решений.
Сценарий 1. Соотношение сторон задается для внутреннего элемента
Круто. Это, возможно, проще. Убедитесь на 100%, что элемент шире, чем область сетки, а затем примените псевдо-элемент для обработки растяжения высоты в соответствии с нужными пропорциями.
Что дает нам следующее:
Обратите внимание, что вам не нужно обязательно применять пропорции через пользовательские свойства. Вы можете видеть, что растяжение достигается за счет нижнего отступа, значение которого может быть задано фиксировано через код или любым другим способом.
Решение через Javascript
Сохранять пропорциональное соотношение сторон блока можно с помощью Javascript функции, которая запоминала бы начальное отношение сторон блока и далее производила бы расчеты и установку высоты по наступлению какого либо события:
Такой пример будет работать и позволит “играться” с отношением сторон, но давай подумаем: по какому событию эта функция должна вызываться? По событию изменения размеров окна? Возможно. А что если ширина контейнера будет изменена не размерами окна, а CSS-анимацией, или через flex, или через другой скрипт. Сколько нюансов придется предусмотреть. Создавать временной интервал, который бы раз в 100 мс производил перерасчет размеров? Все это делает скрипт слишком тяжелым. А если пропорциональных блоков должно быть несколько десятков — тогда наш браузер просто станет зависать. Соответственно, этот вариант так же не годится.
Правильно решение через padding-bottom
Существует нативное решение на чистом CSS, которое позволяет создать пропорциональный блок, не требующий загрузки изображений и использования вспомогательных скриптов. Создать такой пропорциональный блок можно используя особую способность свойства CSS padding-bottom/top рассчитывать свое значение относительно ширины старшего контейнера.
Для этого нам понадобиться три вложенных div элемента:
Старший контейнер div.top будет обладать требуемой шириной, которая может быть выражена в любой единицах измерения.
Вложенному в него контейнеру div.top>div мы установим значение ширины равной 100%, т.е. вложенный блок всегда будет растягиваться на ширину старшего контейнера. А значение padding-bottom вложенного блока div.top>div мы установим равное отношению высоты к ширине в процентах. Т.е. если нам нужен блок с соотношением сторон 2:1, то значением padding-bottom должно быть 50%.
Поскольку padding, по природе своей, является отступом между краем блока и его контентом, третий и заключительный контейнер div.top>div>div мы вынесем за пределы слоя, задав ему абсолютное позиционирование и 100% ширину, и высоту. В него мы разместим контент.
Таким образом, при изменении фактической ширины старшего контейнера div.top, padding-bottom вложенного в него div блока будет всегда принимать высоту, равную 50% от ширины div.top. И Vuole — мы получаем пропорциональный блок, калькулируемый Css процессором.
Это простое решение является самым оптимальным и производительным шаблоном для создания пропорциональных блоков в HTML, так как не загружает браузер ни вспомогательными графическими файлами, ни требует использования Javascript.
Измерение соотношения сторон
Чтобы измерить соотношение сторон, нам нужно разделить ширину на высоту, как показано на следующем рисунке.
Соотношение ширины и высоты 1,33. Значит, это соотношение следует соблюдать. Взгяните на следующий рисунок:
Обратите внимание на изображение справа, значение ширины ÷ высоты составляет 1,02 , что не соответствует исходному соотношению сторон (1,33 или 4: 3).
Вы можете спросить, как придерживатся значения 4: 3 ? Это называется ближайшим нормальным соотношением сторон, и есть инструменты, которые могут помочь нам в его поиске. При работе над дизайном пользовательского интерфейса настоятельно рекомендуется точно знать, какое соотношение сторон изображений вы используете. Использование специального калькулятора может помочь в этом.
Я надеюсь, что концепция соотношения сторон теперь вам понятна. Если вы уже знали об этом, то я надеюсь, что вы просто обновили свои знания.
Решение через
Все, кто занимается HTML-версткой знают, что если тэгу принудительно указать ширину, но не указывать высоту, то высота будет рассчитана автоматически из соотношений высоты к ширине исходного изображения. Таким образом можно создавать пропорциональные блоки с динамической шириной, если помещать внутрь них тэг .
Но использовать такой прием для создания пропорциональных блоков не рационально по ряду причин:
- Для создания пропорционального блока необходимо создавать изображение в графическом редактор с определенными пропорциями, сохранять его на сервер, загружать в браузер;
- Что бы поменять или “поиграться” с отношением сторон блока, нужно каждый раз пересоздавать изображение, что очень долго;
- Необходимость засорять network лишними файлами;
- Браузер тратит дополнительные ресурсы на растровый рендеринг;
Вариант №2 – Сохраняем пропорции высоты и ширины элемента при изменении ширины контента на чистом CSS без псевдоэлементов
Есть второй вариант без псевдоэлементов, но при его использовании блок всегда имеет ширину 100%, поэтому если нужно несколько таких блоков в ряд, то они должны быть помещены в какой-то родитель, у которого уже будет задана нужная ширина относительно остальных элементов на странице.
I want to create a div that can change its width/height as the window's width changes.
Are there any CSS3 rules that would allow the height to change according to the width, while maintaining its aspect ratio?
I know I can do this via JavaScript, but I would prefer using only CSS.
I've come to this Q&A very late, but I must comment. Although it is very disciplined and within the SO rules of everyone answering to try their best to satisfy the "only CSS" demand of the question, it is quite surprising that with the exception of the answer by user007 low down on the page, no-one has mentioned the obvious: no reliable CSS-only solution exists, this problem requires Javascript. A newbie coming to this page could waste valuable time switching from one set of pros/cons to another before the lightbulb goes off: CSS-only won't do.
I wrote a little tool that makes it easy to preview and calculate aspect ratios, aspectrat.io. It also generates the the appropriate CSS/Sass/Less code that you can copy and paste into your projects. Hope people find it useful.
This question is for setting height based on width. If you need the opposite, check out Setting Element Width Based on Height Via CSS.
Решение проблемы
Нам нужны два блочных элемента для достижения желаемого поведения. Нет изображений, нет Javascript.
Итак, что это? Мы определяем псевдоэлемент для нашего ящика и задаем ему margin-top 100% . Поскольку это 100% значение относится к ширине элемента … вы получаете его ( height: 0; padding-bottom: 100%; также будет работать, но тогда вы должны отрегулировать значение padding-bottom каждый раз, когда вы меняете ширину).
Таким образом, наш блок уже выше ширины. Если вы хотите отображать только несколько цветных блоков, тогда уже все готово. Но поскольку пользовательский интерфейс намного сложнее, и если вы также предоставляете некоторый контент, мы добавляем контент в наш блок .box .
Рабочий пример на CodePen:
Другие пропорции
Если вы хотите создать другие коэффициенты, просто измените значение padding-top псевдоэлемента:
Области сетки и элементы, которые для них назначены, не обязательно должны иметь одинаковые размеры
Недавно мы рассматривали данную тему. Та статья задумывалась как вступление для данной, однако рассматриваемая в ней тема была достаточно важной, чтобы вынести ее отдельно.
Помня об этом, мы можем решить, что нам нужна область сетки, а также элемент, который будет растягиваться на всю ее высоту и ширину. Или нам просто нужно задать для элемента соотношение сторон независимо от области сетки для которой он назначен?
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Контент
И вот трюк: мы просто позиционируем блок контента как абсолютный со всеми четырьмя ориентациями, установленными в 0. Это просто покрывает родительский элемент полностью, независимо от того, какой размер он имеет.
Вот и все. Блестяще, не так ли? Даже padding не сломает его, и нет необходимости в box-sizing: border-box здесь.
Реализация соотношения сторон в CSS
Мы привыкли реализовывать соотношение сторон, используя процентное заполнение в CSS. Хорошей новостью является то, что недавно мы получили встроенную поддержку aspect-ratio во всех основных браузерах. Прежде чем погрузиться в новый способ, я сначала объясню старый, добрый и проверенный способ.
Когда элемент имеет вертикальное процентное заполнение, оно будет основано на ширине его родительского элемента. Рассмотрим следующий рисунок:
Когда заголовок имеет padding-top:50%, значение вычисляется на основе его родительской ширины. Так как ширина родителя 200px, то padding-top будет 100px.
Чтобы узнать, какое процентное значение использовать, нам нужно разделить высоту изображения на его ширину. Полученное число — это процент, который вы хотите использовать.
Учтите, что ширина изображения составляет 260 пикселей, а высота — 195 пикселей. Percentage padding = height / width
Результат 195/260 составляет 0,75 (или 75%).
Предположим, что есть сетка карточек, и у каждой из них есть миниатюра. Миниатюры должны быть равными по ширине и высоте.
По какой-то причине автор контента загрузил изображение, размер которого не соответствует другим. Обратите внимание на то, что высота средней карты не такая же, как у других.
Вы можете подумать, ну, мы можем добавить фиксированную высоту и object-fit: cover. Проблема решена, правда? Это не так просто. Это решение не будет хорошо смотреться при изменении размеров области просмотра.
Обратите внимание, что в средней миниатюре с фиксированной высотой, слишком обрезаны края слева и справа, в то время как на мобильных устройствах они слишком широкие. Все это за счет использования фиксированной высоты. Мы можем настроить высоту вручную с помощью различных медиа-запросов, но это не практическое решение.
Нам нужен постоянный размер миниатюр вне зависимости от размера области просмотра. Для этого нам нужно реализовать соотношение сторон, используя процентное заполнение.
Представьте, что нам необходимо создать такой блок в HTML, высота которого бы всегда была относительной от его ширины. К сожалению, в CSS нету таких единиц измерения как отношение к величине другого свойства. Но есть несколько трюков для имитации такого свойства. И сейчас мы их разберем.
Сценарий 3. Принудительное указание
Сетка имеет двумерную компоновку и, если захотите, вы можете задать пропорции, просто принудительно указывая для области сетки соответствие требуемой высоте и ширине. Например, ничто не мешает нам жестко задать высоту и ширину столбцов и строк:
Как пропорционально уменьшать ширину и высоту различных элементов при изменении ширины родительского контейнера?
Для изображений это делается очень просто, задаем свойству height значение auto , при этом максимальную ширину изображения ограничиваем шириной родительского контейнера max-width: 100%;
Проблема в том, что мы не можем задать height: auto; для блочных элементов, например для DIV. В данном случае 100% – это будет высота родителя.
Читайте также: