Как �вер�тать галерею фотографий на CSS Grid

Эта �тать� о�нована на одном из практиче�ких заданий verstaem.online.

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

Перейти к заданию

В �той �татье мы �оздадим галерею фотографий � и�пользованием CSS Grid. По пути разберем, как организовать �етку, правильно оформить карточки изображений, и�пользовать �емантиче�кие теги, работать � изображени�ми и подготовить компонент, который легко ма�штабирует�� при добавлении новых фотографий.

Создаем HTML-разметку

Сначала �оздадим базовую HTML-разметку � помощью Emmet. Дл� �того до�таточно вве�ти ! и нажать Tab. Обратите внимание на атрибут lang. По�кольку о�новной контент �траницы напи�ан на ру��ком �зыке, зде�ь и�пользуем значение ru.

<!doctype html>
<html lang="ru">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Галере� фотографий</title>
  </head>
  <body>
  </body>
</html>

Теперь давайте вер�тать галерею. �ачнем мы � того, что �делаем �екцию — <section>. Внутри разме�тим контейнер — блок, который центрирует контент. �у, а затем реализуем верхушку. Тут будет заголовок и кнопка.

<div class="gallery__top">
  <h2 class="gallery__title">Галере�</h2>
   <button class="gallery__btn">Загрузить</button>
</div>

Саму галерею будет делать �тандартно — �пи�ком, по�кольку у на� одинаковые �лементы идут друг за другом. Дл� �пи�ка, помимо прочего, добавим кла�� grid. Это нужно дл� того, чтобы управл�ть CSS Grid на �том �лементе.

<ul class="gallery__list grid">
   <li class="gallery__item">
   </li>
</ul>

Сама карточка будет реализована как отдельный компонент, отдельный див. Внутри — изображение, заголовок, а также врем� через тег <time>.

<section class="gallery">
  <div class="container">
    <div class="gallery__top">
      <h2 class="gallery__title">Галере�</h2>
      <button class="gallery__btn">Загрузить</button>
    </div>
    <ul class="gallery__list grid">
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/1.png" alt="Горное озеро" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              Горное озеро
            </h3>
            <time datetime="2026-06-12 00:00" class="gallery-card__time">12 Июн� 2026</time>
          </div>
        </div>
      </li>
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/2.png" alt="�очной город" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              �очной город
            </h3>
            <time datetime="2026-06-10 00:00" class="gallery-card__time">10 Июн� 2026</time>
          </div>
        </div>
      </li>
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/3.png" alt="Океан�кий пл�ж" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              Океан�кий пл�ж
            </h3>
            <time datetime="2026-06-08 00:00" class="gallery-card__time">8 Июн� 2026</time>
          </div>
        </div>
      </li>
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/4.png" alt="Ле�на� тропа" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              Ле�на� тропа
            </h3>
            <time datetime="2026-06-06 00:00" class="gallery-card__time">6 Июн� 2026</time>
          </div>
        </div>
      </li>
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/5.png" alt="Водопад" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              Водопад
            </h3>
            <time datetime="2026-06-04 00:00" class="gallery-card__time">4 Июн� 2026</time>
          </div>
        </div>
      </li>
      <li class="gallery__item">
        <div class="gallery-card">
          <img src="img/6.png" alt="Город�кие улицы" class="gallery-card__pic">
          <div class="gallery-card__text">
            <h3 class="gallery-card__title">
              Город�кие улицы
            </h3>
            <time datetime="2026-06-02 00:00" class="gallery-card__time">2 Июн� 2026</time>
          </div>
        </div>
      </li>
    </ul>
  </div>
</section>

Об�зательно заполн�йте alt у изображений по �мы�лу, а также поддерживайте верный формат атрибута datetime.

Добавл�ем �тили

Подключим файл �тилей через <link> и зададим не�колько базовых правил. Дл� �того задани� до�таточно переопределить box-sizing, �бро�ить от�туп у <body> и подключить шрифт Inter, который и�пользует�� в макете.

* {
  box-sizing: border-box;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/InterRegular.woff2");
  font-display: swap;
  font-weight: 400;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/InterMedium.woff2");
  font-display: swap;
  font-weight: 500;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/InterSemiBold.woff2");
  font-display: swap;
  font-weight: 600;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/InterBold.woff2");
  font-display: swap;
  font-weight: 700;
}

body {
  margin: 0;
  padding: 20px;
  background: #f4f6f9;
  font-family: "Inter", sans-serif;
}

Важный нюан�, который вы можете увидеть в коде — �то шрифты. Я намеренно указал font-family внутри @font-face одинаковым, потому что �ам шрифт имеет одно название — Inter, отличают�� лишь его начертани�. Именно так мы и будем делать — указываем шрифт дл� <body> один раз, а затем � помощью font-weight мен�ем толщину шрифта там, где нам нужно.

Далее �оздаем контейнер. Это блок, который должен быть по центру. Видим в макете ширину 1200, но нам �тоит быть умнее, и преду�мотреть от�тупы. Ведь е�ли �айт будет �жимать��, его контент не должен липнуть к кра�м. Чтобы �то реализовать, нужно добавить padding. Именно по�тому, когда мы добавим от�туп, нужно и ширину изменить. Сделаем от�тупы по 15, получит�� 1200+15+15 = 1230.

.container {
  margin: 0 auto;
  padding: 0 15px;
  max-width: 1230px;
}

Далее поработаем � кла��ом grid. �ам нужно определить нашу �етку. Е�ли по�мотреть в макет, увидим три широкие колонки, разделенные от�тупом. Именно на �то и �тоит ориентировать��.

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

Мы задаем display: grid, а затем �вой�тво grid-template-columns, которое управл�ет колонками. �апи�ав функцию repeat(), и передав в нее два параметра (первый — количе�тво колонок, второй — их размер), мы получаем три идентичных по ширине колонки, которые будут т�нуть��. И �юда же добавл�ем gap.

Далее реализуем верхушку. Тут в�е про�то. С помощью flexbox разме�тим �лементы в �троку, ра�кинем их по �торонам, и зададим �тили �амим �лементам. �е забудьте напи�ать font-family дл� кнопки.

.gallery__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 36px;
  gap: 20px;
}

.gallery__title {
  margin: 0;
  font-weight: 700;
  font-size: 32px;
  line-height: 100%;
  color: #111827;
}

.gallery__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 12px;
  padding: 12px 24px;
  font-family: inherit;
  font-weight: 500;
  font-size: 16px;
  color: #f4f6f9;
  background: #111827;
  cursor: pointer;
  transition: background 0.3s;
}

.gallery__btn:hover {
  background: #2a3b5f;
}

В каче�тве �тилей �пи�ка будут только �бро�ы. Сбро� margin, padding и list-style. � дальше уже делаем карточку. Зде�ь об�зательно нужно указать overflow: hidden, иначе картинка не обрежет�� по углу карточки. Самому изображению об�зательно нужно задать display: block и max-width: 100%, чтобы изображение в�тало по размеру карточки. В о�тальном про�то забираем �тили из макета.

.gallery__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.gallery-card {
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  background: #fff;
}

.gallery-card__pic {
  display: block;
  max-width: 100%;
}

.gallery-card__text {
  padding: 16px;
}

.gallery-card__title {
  margin: 0;
  margin-bottom: 8px;
  font-weight: 600;
  font-size: 20px;
  line-height: 100%;
  color: #111827;
}

.gallery-card__time {
  font-weight: 400;
  font-size: 12px;
  line-height: 100%;
  color: #6b7280;
}

Теперь вы умеете �оздавать �овременные галереи изображений � помощью CSS Grid. Мы разобрали �емантиче�кую разметку, организацию карточек, работу � фотографи�ми, и�пользование компонента Grid и подготовили о�нову, которую можно и�пользовать практиче�ки в любом проекте — от блога до интернет-магазина или портфолио.

Решение задачи

предыдущий по�т �ледующий по�т