Как сделать чтобы блок пропорционально уменьшался css
Перейти к содержимому

Как сделать чтобы блок пропорционально уменьшался css

  • автор:

Сохраняем пропорции высоты и ширины элемента при изменении ширины контента на чистом CSS

Как пропорционально уменьшать ширину и высоту различных элементов при изменении ширины родительского контейнера?

Для изображений это делается очень просто, задаем свойству height значение auto , при этом максимальную ширину изображения ограничиваем шириной родительского контейнера max-width: 100%;

Проблема в том, что мы не можем задать height: auto; для блочных элементов, например для DIV. В данном случае 100% — это будет высота родителя.

Решение проблемы

HTML

Нам нужны два блочных элемента для достижения желаемого поведения. Нет изображений, нет Javascript.

 
Aspect ratio of 1:1

CSS

.box < position: relative; width: 50%; /* desired width */ >.box:before < content: ""; display: block; padding-top: 100%; /* initial ratio of 1:1*/ >

Итак, что это? Мы определяем псевдоэлемент для нашего ящика и задаем ему margin-top 100% . Поскольку это 100% значение относится к ширине элемента … вы получаете его ( height: 0; padding-bottom: 100%; также будет работать, но тогда вы должны отрегулировать значение padding-bottom каждый раз, когда вы меняете ширину).

Таким образом, наш блок уже выше ширины. Если вы хотите отображать только несколько цветных блоков, тогда уже все готово. Но поскольку пользовательский интерфейс намного сложнее, и если вы также предоставляете некоторый контент, мы добавляем контент в наш блок .box .

Контент

И вот трюк: мы просто позиционируем блок контента как абсолютный со всеми четырьмя ориентациями, установленными в 0. Это просто покрывает родительский элемент полностью, независимо от того, какой размер он имеет.

.content

Вот и все. Блестяще, не так ли? Даже padding не сломает его, и нет необходимости в box-sizing: border-box здесь.

Другие пропорции

Если вы хотите создать другие коэффициенты, просто измените значение padding-top псевдоэлемента:

/* Other ratios */ .ratio2_1:before < padding-top: 50%; >.ratio1_2:before < padding-top: 200%; >.ratio4_3:before < padding-top: 75%; >.ratio16_9:before

IE7 и ниже

Поскольку IE такой IE, и особенно IE7 — это все, но только не браузер, вы должны сами создать элемент вместо псевдоэлемента в своей разметке, если хотите поддержать IE. Или бросьте на него Javascript, пока он, надеюсь, не сломается. Навсегда.
Мой вольный перевод статьи http://www.mademyday.de/css-height-equals-width-with-pure-css.html.

Рабочий пример на CodePen:

Вариант №2 — Сохраняем пропорции высоты и ширины элемента при изменении ширины контента на чистом CSS без псевдоэлементов

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

HTML

CSS

.box < background-color: red; width: 100%; padding-top: 100%; /* 1:1 Aspect Ratio */ position: relative; >/* If you want text inside of the container */ .content

Другие пропорции

.ratio16_9 < padding-top: 56.25%; /* 16:9 Aspect Ratio */ >.ratio4_3 < padding-top: 75%; /* 4:3 Aspect Ratio */ >.ratio3_2 < padding-top: 66.66%; /* 3:2 Aspect Ratio */ >/* Other ratios */ .ratio8_5 < padding-top: 62.5%; /* 8:5 Aspect Ratio */ >

Рабочий пример на CodePen:

Самый простой пример фиксированного плавающего сайдбара на HTML+CSS+JS. В чем его особенность — при прокрутке…

Еще один фиксированный блок Меню при прокрутке страницы. Было бы замечательно, если бы IE поддерживало…

Простая инструкция, как перенести сайт на CMS WordPress с одного хостинга на другой. На самом…

Суть задачи, чтобы видео, которое находится где-то на странице, включалось только при прокрутке страницы, когда…

Способы пропорционального масштабирования блоков

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

  1. Вложить фоновое изображение в блок посредством тега так, чтобы изображение само растягивало блок по высоте.
  2. Пропорционально менять высоту блока средствами JavaScript .

Способа достичь желаемого при помощи css я не знаю. Хотелось бы узнать у профессионалов, как это принято (и правильно) делать, возможно, найдутся и другие способы, более приемлемые.

Отслеживать
задан 13 сен 2017 в 16:53
1,833 1 1 золотой знак 20 20 серебряных знаков 39 39 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Самый известный трюк — задавать пропорции с помощью height:0 и padding-bottom , так называемый padding-bottom hack.

Значение для padding-bottom расчитывается по формуле:

высота изображения * 100 / ширина изображения

высота изображения / ширина изображения * 100

В данном снипете изображение имеет размеры 1280х720 пикселей, следовательно:

.block < width: 100%; height: 0px; padding-bottom: 56.25%; background: url(http://files.all-free-download.com//downloadfiles/wallpapers/1280_720/heihachi_mishima_tekken_7_4k_17496.jpg) no-repeat center; background-size: cover; >

Зафиксировать пропорции у блока

Можно ли как-то сделать пропорционально масштабируемый блок, если ширину и высоту задавать в процентах, а не в пикселях? Желательно, чтоб при уменьшении высоты браузера не вылазил скроллбар, а блок уменьшался, сохраняя пропорции.

el-d ★★
03.11.16 00:40:57 MSK

конечно можно, ширину можно задавать в %, или vw, высоту в % или vh

Deleted
( 03.11.16 05:28:13 MSK )

Можно, но зачем? Возникнут проблемыс контентом блока. Лучше манипулировать медиазапросами и вьюпортом.

xtala
( 03.11.16 09:17:40 MSK )
Ответ на: комментарий от Deleted 03.11.16 05:28:13 MSK

но тогда вложенные блоки не масштабируются, а обрезаются. при width:auto; height: 90vh или 100% занимают всю область (там должно быть 2 столбика)

el-d ★★
( 03.11.16 13:48:42 MSK ) автор топика

Ты неправильно задаёшь вопрос. Нужно написать что ты делаешь.

anonymous
( 03.11.16 17:59:49 MSK )
Ответ на: комментарий от el-d 03.11.16 13:48:42 MSK

2 столбика чего? если текста то задай родителю column-count

Deleted
( 04.11.16 05:31:08 MSK )
Ответ на: комментарий от Deleted 04.11.16 05:31:08 MSK

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

el-d ★★
( 04.11.16 09:00:03 MSK ) автор топика
Последнее исправление: el-d 04.11.16 09:01:19 MSK (всего исправлений: 2)

Ответ на: комментарий от el-d 04.11.16 09:00:03 MSK

блин, дак ты бы с этого и начинал, тогда тебе поможет flexbox

Deleted
( 04.11.16 10:13:36 MSK )

Мдя, сейчас тебе тут насоветуют. Всё предельно легко реализуется через обычный css. Создается родительский блок с необходимой шириной, внутри него ещё один, с position: relative, высота которого должна быть равна нулю, ширина 100%, и padding-top,в котором указывается процентное соотношение высоты к ширине (56.25% — 16:9, 75% — 4:3 и тд), внутри ещё один блок, с position: absolute, а также left, right, top и bottom равные нулю. Держи полностью рабочий готовый пример.

И последнее — как правильно посчитать значение для padding-top: (высота/ширина)*100% . 16:9 — (9/16)*100=56.25%

Если остались какие-то вопросы по поводу примера — смело задавай.

mr_Heisenberg ★
( 08.11.16 06:28:51 MSK )
Ответ на: комментарий от mr_Heisenberg 08.11.16 06:28:51 MSK

Спасибо, то что нужно!

Только как вложенные блоки по центру выровнять? margin: 0 auto; что-то не выравнивает.

И можно ли сделать так, чтоб родительский блок не превышал высоту браузера?

el-d ★★
( 10.11.16 16:37:37 MSK ) автор топика
Ответ на: комментарий от el-d 10.11.16 16:37:37 MSK

С margin 0 auto — вполне как вариант. А вот с высотой браузера надо поразмыслить. Вечерком отвечу, а то сейчас в маршрутке, ещё и с работы устал.

mr_Heisenberg ★
( 10.11.16 17:13:31 MSK )
Ответ на: комментарий от el-d 10.11.16 16:37:37 MSK

Что ж, наиболее изящным решением будет использовать вычисляемую ширину из смеси calc() , vh и vw для блока с классом necessary-width . Итак из 100vw вычесть разницу 100vw и 100vh, умноженного на нужный коэффициент. К тому же для этого блока надо задать max-width: 100% , иначе он будет вылазить за ширину. Готовый код должен выглядеть вот так, пробелы внутри calc() важны, без них работать не будет. Думаю дальше разберёшься. Единственный минус — не все браузеры поддерживают calc() , vh и vw (пруф 1 и пруф 2). Поиск наименее костыльного костыля я возлагаю на твои плечи, удачи 😉

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

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

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

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

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

  • Для создания пропорционального блока необходимо создавать изображение в графическом редактор с определенными пропорциями, сохранять его на сервер, загружать в браузер;
  • Что бы поменять или “поиграться” с отношением сторон блока, нужно каждый раз пересоздавать изображение, что очень долго;
  • Необходимость засорять 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 элемента:


Here contents


Старший контейнер 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.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *