Адаптивные круглые и другие пропорциональные блоки на CSS

Расскажу принцип адаптивных пропорциональных блоков

'1'

Посмотреть на Codepen

Разметка HTML

<div class="section">
  <div class="container container_full">
    <div class="aspect-ratio">
      <div class="aspect-ratio__flex">
        <div class="aspect-ratio__col">
          <div class="aspect-ratio__item">
            <div class="aspect-ratio__body">
              <img src="https://picsum.photos/1920/1080" alt=""/></div>
          </div>
        </div>
        <div class="aspect-ratio__col">
          <div class="aspect-ratio__item">
            <div class="aspect-ratio__body">
              <img src="https://picsum.photos/1920/1081" alt=""/></div>
          </div>
        </div>
        <div class="aspect-ratio__col">
          <div class="aspect-ratio__item">
            <div class="aspect-ratio__body">
              <img src="https://picsum.photos/1920/1082" alt=""/></div>
          </div>
        </div>
        <div class="aspect-ratio__col">
          <div class="aspect-ratio__item">
            <div class="aspect-ratio__body">
              <img src="https://picsum.photos/1920/1083" alt=""/></div>
          </div>
        </div>
        <div class="aspect-ratio__col">
          <div class="aspect-ratio__item">
            <div class="aspect-ratio__body">
              <img src="https://picsum.photos/1920/1084" alt=""/></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Стили CSS

.container {
  max-width: 1170px;
  margin: 0 auto;
  padding: 0 30px;
}
.container_full {
  max-width: 100%;
}
.aspect-ratio {
  padding: 60px 0;
}
.aspect-ratio * {
  transition: all 0.6s ease;
}
.aspect-ratio__flex {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -15px -30px;
}
.aspect-ratio__col {
  width: 25%;
  padding: 0 15px 30px;
}
.aspect-ratio__item {
  padding-top: 100%;
  position: relative;
}
.aspect-ratio__body {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 50%;
}
.aspect-ratio__body:hover {
  transform: perspective(800px) rotateY(15deg) rotateX(15deg);
  box-shadow: -5px 5px 15px rgba(51,51,51,0.5);
}
.aspect-ratio__body:hover img {
  transform: scale(1.3);
}
.aspect-ratio__body:after {
  width: 94%;
  height: 94%;
  border-radius: 50%;
  display: block;
  content: '';
  border: 1px solid #fff;
  position: absolute;
  top: 3%;
  left: 3%;
}
.aspect-ratio__body img {
  display: block;
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
  object-fit: cover;
  -o-object-position: center;
  object-position: center;
  transition: all 5s ease;
}
@media (max-width: 991.98px) {
  .aspect-ratio__col {
    width: 33.33333333%;
  }
}
@media (max-width: 767.98px) {
  .aspect-ratio__col {
    width: 50%;
  }
}
@media (max-width: 575.98px) {
  .aspect-ratio__col {
    width: 100%;
  }
}

Про адаптивную сетку почитать можно здесь - Адаптивная сетка для каталога

Принцип адаптивных квадратных или круглых блоков

<div class="aspect-ratio__col"> /* Этому блоку задаем ширину в процентах */
  <div class="aspect-ratio__item"> /* Этому блоку задаем padding-top: 100%; и position: relative; */
    <div class="aspect-ratio__body"> /* Этому блоку задаем position: absolute; на всю ширину и высоту родительского блока(<div class="aspect-ratio__item">) */
      <img src="https://picsum.photos/1920/1080" alt=""/></div>
  </div>
</div>
.aspect-ratio__col {
  width: 25%; /* Задаем ширину по 25% - по 4 в ряд */
  padding: 0 15px 30px; /* Задаем отступы */
}
.aspect-ratio__item {
  padding-top: 100%; /* Самое важное свойство - задаем для пропорционального прямоугольника, в данном случае для квадрата */
  position: relative; /* Обязательное свойство, чтобы дочерний блок(.aspect-ratio__body) позиционировать относительно этого блока */
}

/* Растягиваем дочерний блок на весь размер родительского блока */
.aspect-ratio__body {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

Весь принцип состоит из трех пунктов

  1. Создаем блок <div class="aspect-ratio__col"> с шириной в процентах для адаптивности
  2. Добавляем блок <div class="aspect-ratio__item"> со свойствами padding-top и position:relative
  3. Добавляем блок <div class="aspect-ratio__body"> и с помощью position: absolute; растягиваем его на весь размер блока <div class="aspect-ratio__item"> и в него уже помещаем весь необходимый контент

Посмотрим как это работает

'3'

В блок <div class="aspect-ratio__col"> у которого ширина 25% и внутренние отступы по 15px стороны, помещаем блок <div class="aspect-ratio__item"> у которого установлено свойство padding-top: 100%

'3'

Блок <div class="aspect-ratio__item"> считает свободную ширину родительского блока <div class="aspect-ratio__col">, то есть 25% - 30px(левый и правый внутренние отступы) и устанавливает верхний внутренний отступ padding-top в значение 100% от высчитаной свободной ширины родительского блока <div class="aspect-ratio__col">, то есть теперь высота блока равна его ширине.

Блоку <div class="aspect-ratio__item"> также установлено свойство position: relative;, чтобы относительно этого блока позиционировался дочерний блок <div class="aspect-ratio__body">

Далее просто добавляем блок <div class="aspect-ratio__body"> и задаем ему следующие стили, чтобы он занял всю область блока <div class="aspect-ratio__col">

.aspect-ratio__body {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

Если не задать эти стили, то блок <div class="aspect-ratio__body"> будет просто располагаться под верхним внутренним отступом блока <div class="aspect-ratio__item">

Чтобы сделать из квадрата круг, блоку <div class="aspect-ratio__body"> добавляем сделующие стили

.aspect-ratio__body {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  overflow: hidden; /* скрывает часть контента, которых выходит за пределы круга, в данном примере изображение */
  border-radius: 50%; /* устанавливает со всех сторон радиус по половине стороны квадрата и получаем круг */
}


Таким же образом можно сделать адаптивный пропорциональный прямоугольник любого размера

При произвольных размерах прямоугольника очень просто воспользоваться формулой для установки значения padding-top - calc((высота / ширина)*100%) (calc() можно использовать для всех браузеров)

Например, в макете горизонтальный прямоугольник шириной 754px и высотой 312px и нам нужно его пропорционально адаптировать, то блоку <div class="aspect-ratio__item"> устанавливаем

.aspect-ratio__item {
  padding-top: calc((312/754)*100%);
  position: relative;
}

'6'

Если в макете вертикальный прямоугольник шириной 200px и высотой 350px то устанавливаем следующее

.aspect-ratio__item {
  padding-top: calc((350/200)*100%);
  position: relative;
}

'7'



Изображения - https://picsum.photos/