Вариант простой галереи изображений на Flexbox

Сделаем простейшую галерею изображений, используя Flexbox



Прежде чем начать, хотел бы обратить внимание, что у блога есть телеграм канал https://t.me/frontips, где можно узнавать о выходе новых статей и со временем будет появляться больше интересной и полезной информации.

Поддержите развитие блога и канала подпиской!

А теперь перейдём к теме статьи ;) Приятного чтения!



Структура примера

Сделаем 3 варианта галереи c изображениями для рассмотрения различных случаев

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Gallery</title>
    <link rel="stylesheet" href="css/bootstrap-reboot.min.css"/>
    <link rel="preconnect" href="https://fonts.gstatic.com"/>
    <link href="https://fonts.googleapis.com/css2?family=Lora:wght@700&amp;family=Roboto:wght@300;400&amp;display=swap" rel="stylesheet"/>
    <link rel="stylesheet" href="css/main.css"/>
  </head>
  <body>
    <section class="section">
      <div class="container">
        <h2 class="h2">Gallery</h2>

        <!-- Галерея с девятью изображениями расположенных горизонтально -->
        <div class="section__gallery gallery">
          <div class="gallery__flex">
            <div class="gallery__item"><img src="https://picsum.photos/1920/1080" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1081" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1082" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1083" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1084" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1085" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1086" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1087" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1088" alt=""/></div>
          </div>
        </div>

        <!-- Галерея с четырьмя изображениями расположенных горизонтально -->
        <div class="section__gallery gallery">
          <div class="gallery__flex">
            <div class="gallery__item"><img src="https://picsum.photos/1920/1080" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1081" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1082" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1083" alt=""/></div>
          </div>
        </div>

        <!-- Галерея с девятью изображениями расположенных вертикально -->
        <div class="section__gallery gallery">
          <div class="gallery__flex gallery__flex_column">
            <div class="gallery__item"><img src="https://picsum.photos/1920/1080" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1081" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1082" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1083" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1084" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1085" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1086" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1087" alt=""/></div>
            <div class="gallery__item"><img src="https://picsum.photos/1920/1088" alt=""/></div>
          </div>
        </div>

      </div>
    </section>
  </body>
</html>


CSS стили

Блоку <div class="gallery__flex"></div> задаём display: flex; для горизонтального расположения блоков с изображениями

Изначально для всех дочерних блоков с изображениями задаем flex: 1; (сокращенная запись, соответствующая flex-grow: 1;), то есть все блоки занимают одинаковое количество доступного пространства в родительском блоке. Подробнее про записи свойств flex можно посмотреть в документации MDN - flex

При наведении на определённый блок с изображением, меняем ему значение flex, например на flex: 16;. Теперь элемент при наведении будет занимать в 16 раз больше пространства, чем остальные элементы

Для плавного изменения занимаемого пространства используем transition: flex-grow 0.64s ease-in-out;

Чтобы изображения плавно отдалялись при наведении, используем совокупность свойств object-fit, transform и transition (чуть подробнее в комментариях к CSS)

body {
  font-family: 'Roboto', sans-serif;
  background: #202020;
  position: relative;
}
.container {
  max-width: 1140px;
  padding: 0 16px;
  margin: 0 auto;
}
.section {
  padding: 64px 0;
}
.section__gallery {
  margin-bottom: 64px;
}
.section__gallery:last-child {
  margin-bottom: 0;
}
.h2 {
  font-family: 'Lora', serif;
  text-align: center;
  font-size: 48px;
  margin-bottom: 48px;
  color: #fff;
}
.gallery {
  position: relative;
}
.gallery__flex {
  height: 600px;
  display: flex;
}
/* дополнительный класс для вертикального расположения блоков с изображениями */
.gallery__flex_column {
  flex-direction: column;
}
.gallery__item {
  flex: 1; /* изначальное значени для все элементов */
  transition: flex-grow 0.64s ease-in-out; /* для плавного изменения занимаемого пространства */

  /* если блоки изображений отображаются вертикально, им необходимо задать overflow: hidden; или min-height: 0; иначе блоки с изображениями не будут сжиматься и выйдут за границы блока галереи */
  overflow: hidden;
  min-height: 0;
}
.gallery__item:hover {
  flex: 16; /* при наведении меняем значение flex */
}
.gallery__item img {
  /* пропорционально растягиваем изображение на весь блок <div class="gallery__item"></div> */
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
  object-fit: cover;
  display: block;
  /* для плавного перехода используем transition */
  transition: transform 1.6s ease-in-out;
  /* изначально изображение немного увеличено */
  transform: scale(1.1);
}
.gallery__item:hover img {
  transform: scale(1); /* при наведении убираем масштабирование изображения */
}


Получаем следующий результат


Чтобы расположить блоки изображений вертикально, добавим для блока <div class="gallery__flex"></div> дополнительный класс gallery__flex_column со свойством flex-direction: column;

В таком случае есть одна особенность, элементам <div class="gallery__item"></div> необходимо задать overflow: hidden; или min-height: 0; иначе блоки с изображениями не будут сжиматься по высоте и выйдут за границы блока галереи

Архив с примером можно скачать по ссылке



Буду рад, если статья оказалась полезной

Спасибо за ваше внимание и уделённое время!



Друзья, стараюсь для вас, поддержите проект!

Подписывайтесь, впереди много всего интересного и полезного ;)

Telegram - https://t.me/frontips

VK - https://vk.com/frontips