Понимание принципа работы пропорционального блока в HTML

Vladimir Morulus
3 min readSep 18, 2016

Представьте, что нам необходимо создать такой блок в HTML, высота которого бы всегда была относительной от его ширины. К сожалению, в CSS нету таких единиц измерения как отношение к величине другого свойства. Но есть несколько трюков для имитации такого свойства. И сейчас мы их разберем.

Решение через <img />

Все, кто занимается HTML-версткой знают, что если тэгу <img /> принудительно указать ширину, но не указывать высоту, то высота будет рассчитана автоматически из соотношений высоты к ширине исходного изображения. Таким образом можно создавать пропорциональные блоки с динамической шириной, если помещать внутрь них тэг <img />.

Но использовать такой прием для создания пропорциональных блоков не рационально по ряду причин:

  • Для создания пропорционального блока необходимо создавать изображение в графическом редактор с определенными пропорциями, сохранять его на сервер, загружать в браузер;
  • Что бы поменять или “поиграться” с отношением сторон блока, нужно каждый раз пересоздавать изображение, что очень долго;
  • Необходимость засорять network лишними файлами;
  • Браузер тратит дополнительные ресурсы на растровый рендеринг;

Решение через Javascript

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

function createProportionalBlockHandler(el) {
var cs=window.getComputedStyle(el),
ratio = parseInt(cs.height)/parseInt(cs.width);
return function () {
cs.style.height = Math.round(parseInt(cs.width*ratio)+'px';
}
}
$(window).on('resize', createProportionalBlockHandler(el));

Такой пример будет работать и позволит “играться” с отношением сторон, но давай подумаем: по какому событию эта функция должна вызываться? По событию изменения размеров окна? Возможно. А что если ширина контейнера будет изменена не размерами окна, а CSS-анимацией, или через flex, или через другой скрипт. Сколько нюансов придется предусмотреть. Создавать временной интервал, который бы раз в 100 мс производил перерасчет размеров? Все это делает скрипт слишком тяжелым. А если пропорциональных блоков должно быть несколько десятков — тогда наш браузер просто станет зависать. Соответственно, этот вариант так же не годится.

Правильно решение через padding-bottom

Существует нативное решение на чистом CSS, которое позволяет создать пропорциональный блок, не требующий загрузки изображений и использования вспомогательных скриптов. Создать такой пропорциональный блок можно используя особую способность свойства CSS padding-bottom/top рассчитывать свое значение относительно ширины старшего контейнера.

Для этого нам понадобиться три вложенных div элемента:

<div class="top">
<div>
<div>Here contents</div>
</div>
</div>

Старший контейнер div.top будет обладать требуемой шириной, которая может быть выражена в любой единицах измерения.

div.top {
width:100%;
}

Вложенному в него контейнеру div.top>div мы установим значение ширины равной 100%, т.е. вложенный блок всегда будет растягиваться на ширину старшего контейнера. А значение padding-bottom вложенного блока div.top>div мы установим равное отношению высоты к ширине в процентах. Т.е. если нам нужен блок с соотношением сторон 2:1, то значением padding-bottom должно быть 50%.

div.top > div {
position:relative;
width:100%;
padding-bottom:50%; // Отношение высоте к ширине
}

Поскольку padding, по природе своей, является отступом между краем блока и его контентом, третий и заключительный контейнер div.top>div>div мы вынесем за пределы слоя, задав ему абсолютное позиционирование и 100% ширину, и высоту. В него мы разместим контент.

div.top > div > div {
position:absolute;
width:100%;
height:100%;
}

Таким образом, при изменении фактической ширины старшего контейнера div.top, padding-bottom вложенного в него div блока будет всегда принимать высоту, равную 50% от ширины div.top. И Vuole — мы получаем пропорциональный блок, калькулируемый Css процессором.

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

Верстайте с умом.

--

--