Создание галереи изображений с фильтрами

Тренажер по CSS для пользователей с начальным уровнем подготовки.

Тренажер CSS

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

Список тем

Создание основной сетки галереи

id: 37532_gallery-flex-layout-01

Начнем с основ. Ваша задача - использовать CSS Flexbox для расположения элементов галереи (`.gallery-item`) внутри контейнера `.image-gallery`. Элементы должны выстраиваться в ряд и автоматически переноситься на следующую строку, если не хватает места в контейнере. Также добавьте небольшой отступ между элементами.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  margin: 0 5px;
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
}

.image-gallery {
  /* Активируйте Flexbox */
  input1: flex;
  /* Разрешите перенос элементов */
  input2: wrap;
  /* Добавьте отступ между элементами */
  input3: 10px;
}

.gallery-item {
  /* Стили для элемента будут добавлены позже */
  border: 1px solid #eee; /* Временная рамка для наглядности */
  box-sizing: border-box;
}

.gallery-item img {
  display: block;
  max-width: 100%;
  height: auto;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Для контейнера `.image-gallery` примените свойство `display` со значением `flex`, чтобы активировать Flexbox. Затем используйте свойство `flex-wrap` со значением `wrap` для разрешения переноса элементов. Для создания отступов между flex-элементами используйте свойство `gap`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Определение размера элементов галереи

id: 37532_gallery-item-sizing-02

Теперь задайте размер для каждого элемента галереи (`.gallery-item`). Учитывая ширину iframe (около 372px) и отступ (`gap`), настройте базовый размер flex-элементов так, чтобы в одном ряду помещалось примерно два изображения. Используйте свойство, определяющее базовый размер flex-элемента.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  margin: 0 5px;
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gallery-item {
  /* Задайте базовый размер flex-элемента */
  input1: calc(50% - 5px); /* Пример для двух колонок */
  border: 1px solid #eee;
  box-sizing: border-box;
}

.gallery-item img {
  display: block;
  max-width: 100%;
  height: auto;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Используйте свойство `flex-basis` для `.gallery-item`. Чтобы разместить два элемента в ряду с учетом `gap: 10px`, можно использовать вычисляемое значение, например, `calc(50% - 5px)`. Также можно использовать свойство `width`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Корректное отображение изображений

id: 37532_gallery-image-fit-03

Изображения могут иметь разные пропорции. Сделайте так, чтобы каждое изображение (`img` внутри `.gallery-item`) полностью заполняло свой контейнер по ширине, имело фиксированную высоту (например, 120px) и при этом сохраняло свои пропорции, обрезаясь, если это необходимо для заполнения.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  margin: 0 5px;
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gallery-item {
  flex-basis: calc(50% - 5px);
  border: 1px solid #eee;
  box-sizing: border-box;
  /* Скройте части изображения, выходящие за границы */
  input1: hidden;
}

.gallery-item img {
  display: block;
  /* Задайте ширину, чтобы заполнить контейнер */
  input2: 100%;
  /* Задайте фиксированную высоту */
  input3: 120px;
  /* Настройте масштабирование и обрезку */
  input4: cover;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Для тега `img` внутри `.gallery-item` установите `width: 100%`, чтобы изображение занимало всю ширину родителя. Задайте фиксированную `height` (например, 120px). Используйте свойство `object-fit` со значением `cover`, чтобы изображение масштабировалось с сохранением пропорций и обрезалось для заполнения контейнера. Также добавьте `overflow: hidden;` к `.gallery-item`, чтобы скрыть обрезанные части.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Стилизация кнопок фильтра

id: 37532_gallery-filter-buttons-style-04

Придайте кнопкам фильтра (`.filter-button`) более законченный вид. Убедитесь, что они отображаются как блочно-строчные элементы для корректного применения отступов и расположения в строку. Установите внутренние отступы и измените вид курсора при наведении на 'pointer'.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  /* Установите тип отображения */
  input1: inline-block;
  margin: 0 5px;
  /* Задайте внутренние отступы */
  input2: 8px 15px;
  /* Измените вид курсора */
  input3: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gallery-item {
  flex-basis: calc(50% - 5px);
  border: 1px solid #eee;
  box-sizing: border-box;
  overflow: hidden;
}

.gallery-item img {
  display: block;
  width: 100%;
  height: 120px;
  object-fit: cover;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Для селектора `.filter-button` используйте свойство `display` со значением `inline-block`. Добавьте свойство `padding` для установки внутренних отступов (например, `8px 15px`). Измените вид курсора с помощью свойства `cursor` со значением `pointer`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Эффект при наведении на кнопки

id: 37532_gallery-button-hover-05

Добавьте визуальный отклик при наведении курсора мыши на кнопки фильтра. Измените цвет фона кнопки, когда на нее наведен курсор. Используйте для этого соответствующий псевдокласс.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  display: inline-block;
  margin: 0 5px;
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
  transition: background-color 0.2s ease; /* Для плавности эффекта */
}

/* Правило для состояния наведения */
.filter-button:input1 {
  /* Измените цвет фона */
  input2: #e0e0e0;
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gallery-item {
  flex-basis: calc(50% - 5px);
  border: 1px solid #eee;
  box-sizing: border-box;
  overflow: hidden;
}

.gallery-item img {
  display: block;
  width: 100%;
  height: 120px;
  object-fit: cover;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Используйте псевдокласс `:hover` для селектора `.filter-button`. Внутри правила для этого псевдокласса измените свойство `background-color` на другое значение (например, `#e0e0e0`).
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку

Выделение изображений по атрибуту

id: 37532_gallery-attribute-selector-06

Важным шагом к фильтрации является возможность стилизовать элементы на основе их атрибутов. Используйте селектор атрибута, чтобы выбрать все элементы галереи (`.gallery-item`), у которых `data-category` равен 'nature', и примените к ним особое оформление, например, измените цвет рамки.

CSS
.filter-controls {
  margin-bottom: 15px;
  text-align: center;
}

.filter-button {
  display: inline-block;
  margin: 0 5px;
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid #ddd;
  background-color: #f0f0f0;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.filter-button:hover {
  background-color: #e0e0e0;
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gallery-item {
  flex-basis: calc(50% - 5px);
  border: 1px solid #eee; /* Стандартная рамка */
  box-sizing: border-box;
  overflow: hidden;
  transition: border-color 0.3s ease; /* Плавный переход для рамки */
}

/* Выделите элементы с категорией 'nature' */
.gallery-iteminput1 {
  /* Измените цвет рамки */
  input2: green;
}

.gallery-item img {
  display: block;
  width: 100%;
  height: 120px;
  object-fit: cover;
}
HTML
<div class="gallery-container">
  <div class="filter-controls">
    <button class="filter-button" data-filter="all">All</button>
    <button class="filter-button" data-filter="nature">Nature</button>
    <button class="filter-button" data-filter="tech">Tech</button>
    <button class="filter-button" data-filter="abstract">Abstract</button>
  </div>
  <div class="image-gallery">
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/1.png" alt="Nature Image 1">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/2.png" alt="Tech Image 1">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/4.png" alt="Abstract Image 1">
    </div>
    <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/5.png" alt="Nature Image 2">
    </div>
    <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/6.png" alt="Tech Image 2">
    </div>
    <div class="gallery-item" data-category="abstract">
      <img src="https://naytikurs.ru/img/7.png" alt="Abstract Image 2">
    </div>
     <div class="gallery-item" data-category="nature">
      <img src="https://naytikurs.ru/img/8.png" alt="Nature Image 3">
    </div>
     <div class="gallery-item" data-category="tech">
      <img src="https://naytikurs.ru/img/9.png" alt="Tech Image 3">
    </div>
  </div>
</div>
Создайте CSS-правило, комбинируя селектор класса `.gallery-item` и селектор атрибута `[data-category="nature"]`. Внутри этого правила измените свойство `border-color` (или `border`) на желаемый цвет (например, `green`).
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Показать подсказку
НайтиКурс.Ру