Высота div равная ширине на CSS

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

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

img {
	max-width: 100%;
	height: auto;
}

Но что делать если такое поведение требуется для блочного элемента (например для тега div)?

Свойство height: auto; здесь уже не поможет, поэтому нужно искать другое решение. Разумеется, для изменения размеров, мы можем применять JavaScript, но тогда это будет не самым лучшим решением. Поэтому давайте все же постараемся реализовать все это на чистом CSS.

Смотреть видеоурок

Для начала создадим необходимую HTML-структуру:

HTML

<div class="responsive-box">
<div class="content">Какой-то текст...</div>
</div>

Нам нужно создать два блочных элемента, содержимое размещаем внутри второго блока (в нашем случае это блок с классом .content).

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

Затем добавим CSS.

CSS

.responsive-box {
	position: relative;
	width: 30%; /* Произвольная ширина, которая требуется для блока */
}
.responsive-box::before {
	content: "";
	display: block;
	padding-top: 100%; /* С помощью этого padding мы задаем высоту равную ширине блока */
}
.content {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background: url(images/bg.jpg) no-repeat center center; /* Задаем фон, если требуется */
    background-size: cover; /* Растягиваем фон под размеры блока, если требуется */
}

Как видите, для блока .content, мы можем смело задавать какой-то фон и этот фон также будет растягивать в зависимости от размеров блока.

Поглядите, что у нас получилось. Для этого зайдите на страницу "Демо" и попробуйте изменить размеры окна браузера.

Другие соотношения сторон

В примере выше, мы реализовали блок, у которого высота равнялась ширине. В итоге мы создали адаптивный квадрат с соотношением сторон 1:1.

Если нам требуется другое соотношение сторон, то для этого нужно поиграться со свойством:

.responsive-box::before {
	padding-top: 50%; /* С помощью этого padding мы задаем высоту в 2 раза меньше, чем ширина блока */
}

Сейчас мы указали значение 50%, вместо 100%, как это было на первом примере. Таким образом, мы изменили соотношение сторон нашего блока, теперь оно будет равно 1:2.
То есть, высота будет в два раза меньше, чем ширина.

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

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

  • познавательно и полезно. спасибо

  • 01.08.2018 11:48

    Спасибо! Интересно. Но это если размеры и ориентация бэкграунда известны и неизменны. А вот если у меня на страничке идут список новостей, к ним изображения разные: где то альбомная ориентация, где то портретная. Все сделаны как фон. Нужно чтобы, если горизонтальное изображение – растягивалось на всю ширину, если вертикальное на всю высоту. И как тут с padding-top подгадаешь? Можно конечно сделать просто картинками img , но мне интересно можно ли как то с фоном такое сделать. Я же не буду у каждой новости измерять соотношения сторон превьюшки и прописывать для каждой новости свой padding-top )

    • Почему padding-top нельзя подгадать?
      Задаете padding-top меньше 100%, получится прямоугольник в альбомной ориентации.
      Задаете padding-top больше 100%, получится прямоугольник в портретной ориентации.

      • 02.08.2018 11:22

        Да, я понимаю. Я имею ввиду, как это автоматизировать. Вот представьте, если к примеру на страничке будет хотя бы 30 разных изображений, это и прописывать каждому. Я так понимаю тут без JS не обойтись. Только вот как получать размеры изображений. Подобное реализовано на https://www.pinterest.ru, но вот как я пока не понял )

      • Да, чтобы разместить фото, как на этом сайте, без JS не обойтись.
        Можете посмотреть плагин https://masonry.desandro.com/ он позволяет создавать подобные плитки из фоток.

  • Вы учите делать не кроссбраузерную верстку! В firefox padding top и bottom в процентах рассчитываются от высоты блока, а не от его ширины как это делает хром! То есть для FireFox падинги 100: = 0px. а значит этот способ не работает!

    • Я первый раз слышу, что этот способ не работает в firefox.
      Можете показать конкретный пример, где он не работает?

    • 02.08.2018 21:22

      Спасибо, возьму на заметку. А вы не подскажите, этот плагин только с изображениями работает или можно блоки с фоном так делать? А вообще я к чему эту дискуссию завел ) Я просто сейчас начал пробовать ленивую загрузку использовать, вот для неё как раз и нужна эта фишка с padding-bottom для респонзив изображений, т.к. пока до изображения не проскролишь, там находиться пустышка под размер будущего изображения, чтобы при появлении изображения небыло скачков. Так вот если будет такая плитка, то padding-bottom будет у каждого изображения разный и вот мне интересно как это реализовывается. За плитку спасибо, но тут уже получается такой вопрос: Как сделать правильно ленивую загрузку для плитки? ))

      • На сколько я знаю, плагин работает с любым контентом. Что касается ленивой загрузки, то конкретно с данным плагином я ее не совмещал, поэтому что-то конкретное вряд ли смогу подсказать. Надо читать документацию плагина.

  • 07.02.2018 08:16

    Может: адаптивный img не min-width, а – max-width: 100%?

  • 16.01.2018 18:31

    Уау, сайт очень крутой, пока посмотрел только твоё видео про блочные элементы, но сейчас посмотрел статьи, очень круто) спасибо тебе большое)))) и красота сайта конечно выше всех похвал))

  • Добрый день. Скажите, если добавить такой код в css, почему padding-top примет значение width:50% и задаст высоту равную ширине? разве padding и width связаны? Спасибо большое.

    .responsive-box{
    position:relative;
    width:50%;
    }

    .responsive-box:before{
    content:"";
    display:block;
    padding-top:100%;
    }

  • что-то я не соображу. а если мне надо таких квадратов 8 штук в 2 ряда по 4 в каждом и чтобы все растягивалось под ширину экрана как быть? я пробовал выставить несколько таких дивов, но они сливаются как бы в один или начинают строиться друг под другом а нужна конструкция
    0000
    0000
    вот такого типа каждый квадрат 25% от ширины экрана и столько же в высоту

  • Спасибо, очень для меня актуально и как всегда очень толково преподнесено.

  • Очень интересно и познавательно.
    Благодарю автора.

  • Спасибо за полезный урок

  • http://prntscr.com/ag3htn

    • Николай, псевдоэлемент :before работает совместно со свойством content. C помощью этого свойства мы вставляем какой-то контент до содержимого нашего элемента .responsive-box

      Если бы мы написали .responsive-box::before { content: "123" }

      То у нас перед содержимым появились бы цифры 123. То есть, что написано в свойстве контент, то и добавится.

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

      Вообще не указывать свойство content мы не можем, т.к. псевдоэлемент не добавится без свойства content.

    • Александр Пауков, Вот теперь ясно и понятно) Спасибо я Вам очень благодарен!!!