Zoom-эффект - масштаб и позиционирование изображения

Рассмотрим очень полезное свойство для изображений - object-fit. Опишу как достигается zoom-эффект, а также посмотрим другие полезные применения этого свойства

'1'

Пример на Codepen

HTML-разметка примера

<div class="section">
  <div class="container">
    <div class="object-fit">
      <div class="object-fit__flex">
        <div class="object-fit__col">
          <div class="object-fit__card">
            <div class="object-fit__image">
              <img src="https://picsum.photos/1920/1080" alt=""/>
            </div>
            <div class="object-fit__body">
              <div class="object-fit__title">Lorem ipsum</div>
              <div class="object-fit__text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla, dolor.</div>
            </div>
          </div>
        </div>
        <div class="object-fit__col">
          <div class="object-fit__card">
            <div class="object-fit__image">
              <img src="https://picsum.photos/1920/1081" alt=""/>
            </div>
            <div class="object-fit__body">
              <div class="object-fit__title">Sit amet</div>
              <div class="object-fit__text">Nulla, dolor. sit amet, consectetur adipisicing elit. Nulla, dolor.</div>
            </div>
          </div>
        </div>
        <div class="object-fit__col">
          <div class="object-fit__card">
            <div class="object-fit__image">
              <img src="https://picsum.photos/1920/1082" alt=""/>
            </div>
            <div class="object-fit__body">
              <div class="object-fit__title">Nulla, dolor</div>
              <div class="object-fit__text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla, dolor.</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

CSS стили примера

.container {
  max-width: 1170px;
  margin: 0 auto;
  padding: 0 30px;
}
.object-fit {
  padding: 60px 0;
}
.object-fit__flex {
  margin: 0 -15px -30px;
  display: flex;
  flex-wrap: wrap;
}
.object-fit__col {
  padding: 0 15px 30px;
  width: 33.33333333%;
}
.object-fit__card {
  border-radius: 10px;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.object-fit__card:hover .object-fit__image img {
  transform: scale(1.3);
}
.object-fit__image {
  height: 250px;
  overflow: hidden;
}
.object-fit__image img {
  -o-object-fit: cover;
  object-fit: cover;
  width: 100%;
  height: 100%;
  display: block;
  transition: all 3s ease-in-out;
}
.object-fit__body {
  padding: 30px;
  flex: 1;
  background: linear-gradient(325deg, rgba(63,139,251,0.9) 0%, rgba(70,86,252,0.9) 100%);
  display: flex;
  flex-direction: column;
  color: #fff;
}
.object-fit__title {
  font-weight: bold;
  font-size: 24px;
  margin-bottom: 15px;
  text-align: center;
}
.object-fit__text {
  text-align: center;
  font-size: 16px;
  flex-grow: 1;
}

Подробнее про адаптивную сетку - Адаптивная сетка для каталога



Все что нужно для zoom-эффекта

<div class="object-fit__image"> <!--Родительский элемент, который будет обрезать часть изображения, выходящую за пределы этого блока -->
  <img src="https://picsum.photos/1920/1080" alt=""/>
</div>
.object-fit__image {
  height: 250px /* указываем размеры блока с изображением, в данном случае высоту 250px, ширина будет 100% по-умолчанию */;
  overflow: hidden /* Обрезаем часть изображения, выходящую за пределы этого блока */;
}
.object-fit__image img {
  -o-object-fit: cover;
  object-fit: cover /* свойство которое увеличивает размер изображения для полного заполнения блока, при этом не искажает его (аналог background-size: cover;) */;
  width: 100% /* для свойства object-fit необходимо указывать размеры области изображения, так как нам нужно разместить изображение на всю область родительского блока, то задаем ширину и высоту по 100% */;
  height: 100% /* для свойства object-fit необходимо указывать размеры области изображения, так как нам нужно разместить изображение на всю область родительского блока, то задаем ширину и высоту по 100% */;
  display: block /* Убираем пустое место в несколько пикселей под изображением, подробнее по ссылке - https://learn.javascript.ru/space-under-img */
  transition: all 3s ease-in-out; /* плавная анимация */;
}
.object-fit__image:hover .object-fit__image img {
  transform: scale(1.3) /* при наведении на родительский блок увеличиваем размер изображения */;
}


Как работает object-fit

Возьмем 3 изображения разных размеров и посмотрим на их поведение

Первый блок - квадратное изображение меньше родительского блока 150px*150px
Второй блок - вертикальное изображение больше родительского блока 250px*300px
Третий блок - горизонтальное изображение больше родительского блока 400px*150px

Для наглядности у родительского элемента уберу свойтво overflow:hidden


Пример 1 - изображения должны занимать все пространство родительского блока и не должны быть искажены (например, в качестве фона)

Свойства - object-fit не установлено, размеры области изображений не заданы (зеленая рамка - размер области изображения равен размерам самого изображения)

.object-fit__image img {
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

Результат - изображения выходят за пределы родителького блока

'2'


Пример 2 - та же задача - изображения должны занимать все пространство родительского блока и не должны быть искажены (например, в качестве фона)

Свойства - object-fit не установлено(по-умолчанию object-fit: fill;), ширина и высота области изображений по 100% (зеленая рамка - размер области изображения равен всей области родительского блока)

.object-fit__image img {
  width: 100%;
  height: 100%;
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

Результат - изображения занимают все пространство родительского блока, но при этом искажены. Такой же результат дает значение object-fit: fill;

'3'


Пример 3 - та же задача - изображения должны занимать все пространство родительского блока и не должны быть искажены (например, в качестве фона)

Свойства - установлено object-fit: cover;, размеры области изображений не заданы (зеленая рамка - размер области изображения равен размерам самого изображения)

.object-fit__image img {
  -o-object-fit: cover;
  object-fit: cover;
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

Результат - свойство object-fit: cover; не работает, так как не установлены размеры области изображений (зеленая рамка - размер области изображения равен размерам самого изображения)

'2'


Пример 4 - та же задача - изображения должны занимать все пространство родительского блока и не должны быть искажены (например, в качестве фона)

Свойства - установлено object-fit: cover;, ширина и высота области изображений по 100% (зеленая рамка - размер области изображения равен всей области родительского блока)

.object-fit__image img {
  -o-object-fit: cover;
  object-fit: cover;
  width: 100%;
  height: 100%;
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

Результат - изображения занимают все пространство родительского блока, при этом пропорции сохранены и изображения отцентрованы

'4'


Пример 5 - изображения должны быть показаны полностью(не должно быть обрезанных частей, например схема или иконка), пропорции должны быть сохранены, при этом если изображения меньше родительского блока оно не должны растягиваться, а если изображения больше родительского блока, то изображения не должны превышать его размеров

Свойства - установлено object-fit: scale-down;, ширина и высота области изображений по 100% (зеленая рамка - размер области изображения равен всей области родительского блока)

.object-fit__image img {
  -o-object-fit: scale-down;
  object-fit: scale-down;
  width: 100%;
  height: 100%;
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

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

'5'


Пример 6 - изображения должны быть показаны полностью(не должно быть обрезанных частей, например схема или иконка), пропорции должны быть сохранены, при этом если изображения меньше родительского блока должны растягиваться, а если изображения больше родительского блока, то изображения не должны превышать его размеров

Свойства - установлено object-fit: contain;, ширина и высота области изображений по 100% (зеленая рамка - размер области изображения равен всей области родительского блока)

.object-fit__image img {
  -o-object-fit: contain;
  object-fit: contain;
  width: 100%;
  height: 100%;
  border: 5px solid #44af69;
  display: block;
  transition: all 3s ease-in-out;
}

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

'6'


Важно понять, что при указании свойства object-fit элементу img (.object-fit__image img) ширина и высота в CSS задается не самому изображению, а области изображения (зеленая рамка в примерах выше), где будет расположен сам объект изображения, следовательно если размеры области не указать, свойство object-fit работать не будет

При object-fit: none; изображение игнорирует размеры родительского блока и использует свои исходные размеры, при этом если установлено object-fit: none; изображение будет отцентровано в родительском блоке, так как object-fit есть сопутствующее свойство object-position, которое по-умолчанию установлено object-position: center;

Свойство object-position, принимает значения аналогично background-position, например при object-position: center; - изображение будет расположено по центру родительского блока, а при object-position: left top; - изображение будет расположено слева сверху и так далее

Свойство object-fit поддерживается во всех браузерах, кроме Internet Explorer

Ссылка на документацию по object-fit - MDN web docs



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