Простая галерея изображений на HTML, CSS и JavaScript

Создание простой галереи изображений с помощью HTML, CSS и JavaScript — эффективный способ изучить основы фронтенд-разработки. Галерея позволяет увеличить изображение по клику на миниатюру и плавно переключаться между ними.
Важно: все пути к изображениям и имена файлов в примерах соответствуют структуре проекта, где папка images находится рядом с index.html.
Что вы получите в этой статье
- Пошаговая инструкция по созданию UI галереи.
- Полные примеры файлов: index.html, styles.css, script.js.
- Советы по доступности и адаптивности.
- Контрольный список и тест-кейсы для приёмки.
- Варианты расширения и возможные ошибки.
Как создать интерфейс галереи
- Создайте файл index.html и добавьте базовую структуру страницы:
Image Gallery
Image Gallery
Выберите миниатюру ниже, чтобы просмотреть изображение в увеличенном виде
- Создайте папку images и положите в неё изображения image1.jpg…image10.jpg.

- Файл styles.css (базовый стиль + адаптивность и акцент при выборе миниатюры):
:root{
--gallery-width: 700px;
--thumb-size: 88px;
--gap: 12px;
}
body{
font-family: Arial, Helvetica, sans-serif;
margin: 20px;
color: #222;
background: #f7f7f7;
}
.intro{
text-align: center;
}
h2{
font-size: 32px;
margin-bottom: 6px;
}
#image-gallery{
width: var(--gallery-width);
max-width: 95%;
margin: 20px auto;
background: #fff;
padding: 16px;
border-radius: 8px;
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
}
#current-image{
width: 100%;
height: auto;
display: block;
border-radius: 6px;
}
#image-thumbs{
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: var(--gap);
margin-top: 16px;
}
.thumb{
width: var(--thumb-size);
height: var(--thumb-size);
object-fit: cover;
cursor: pointer;
border-radius: 6px;
border: 2px solid transparent;
transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.thumb:hover{
transform: translateY(-4px);
box-shadow: 0 8px 18px rgba(0,0,0,0.12);
}
.thumb:focus{
outline: none;
border-color: #2b8cff;
}
.thumb.selected{
border-color: #2b8cff;
box-shadow: 0 10px 20px rgba(43,140,255,0.12);
}
@media (max-width: 480px){
:root{ --thumb-size: 64px; }
h2{ font-size: 22px; }
}- Скрипт script.js, который динамически создаёт миниатюры и добавляет обработчики (с поддержкой клавиатуры):
// script.js
var imageThumbs = document.getElementById('image-thumbs');
var currentImage = document.getElementById('current-image');
var totalImages = 10; // измените при необходимости
function createThumb(index){
var thumb = document.createElement('img');
thumb.src = 'images/image' + index + '.jpg';
thumb.alt = 'Изображение ' + index;
thumb.classList.add('thumb');
thumb.setAttribute('tabindex', '0');
thumb.setAttribute('role', 'button');
thumb.dataset.index = index;
// ленивый режим загрузки для миниатюр
thumb.loading = 'lazy';
thumb.addEventListener('click', function(){
setCurrentImage(this);
});
thumb.addEventListener('keydown', function(e){
if(e.key === 'Enter' || e.key === ' '){
e.preventDefault();
setCurrentImage(this);
}
});
return thumb;
}
function setCurrentImage(thumb){
currentImage.src = thumb.src;
currentImage.alt = thumb.alt;
// отметить выбранную миниатюру визуально
var prev = imageThumbs.querySelector('.thumb.selected');
if(prev) prev.classList.remove('thumb', 'selected');
thumb.classList.add('selected');
// для управления фокусом и доступности можно устанавливать aria-current
thumb.setAttribute('aria-current', 'true');
if(prev) prev.removeAttribute('aria-current');
}
// Создаём все миниатюры
for (let i = 1; i <= totalImages; i++){
var t = createThumb(i);
imageThumbs.appendChild(t);
// по умолчанию пометить первую миниатюру как выбранную
if(i === 1){
t.classList.add('selected');
}
}Важно: в старых браузерах вместо let используйте var и замыкания. В современных проектах предпочтительна запись с let/const.
Как миниатюры меняют основное изображение
JavaScript генерирует элементы для миниатюр и прикрепляет обработчики событий. При клике (или нажатии Enter/Space) у миниатюры берётся её src/alt и копируется в крупное изображение.


Расширения и улучшения (варианты)
- Добавить переходы: плавное появление крупного изображения через opacity/transform.
- Поддержка свайпа на мобильных устройствах (touch events или библиотека Hammer.js).
- Lazy-loading для крупных изображений: использовать loading=”lazy” или IntersectionObserver.
- Миниатюры по категориям: организовать папки и фильтры.
- Использовать CSS Grid вместо flex для расположения миниатюр.
- Подключить lightbox-библиотеку для просмотра в полноэкранном режиме.
Доступность и SEO
- Добавляйте осмысленные alt-атрибуты (не «image1», а «Пейзаж: озеро на рассвете»), если такие данные доступны. В нашем учебном примере используются базовые alt “Изображение N”.
- Делайте миниатюры фокусируемыми tabindex=”0” и реагирующими на клавиши Enter/Space.
- Для динамически меняемого контента можно пометить контейнер aria-live=”polite”, чтобы скринридеры уведомляли пользователей.
Критерии приёмки
- При загрузке страницы отображается первое изображение.
- Миниатюры видны и кликабельны.
- Клик по миниатюре меняет src и alt у #current-image.
- Миниатюра имеет визуальное состояние выбранная/не выбрана.
- Галерея корректно работает на мобильных экранах.
- Управление с клавиатуры (Tab + Enter/Space) переключает изображения.
Тест-кейсы и контрольный список
- TC1: Открыть index.html в браузере — первая картинка отображается.
- TC2: Кликнуть на любую миниатюру — крупное изображение обновилось.
- TC3: Навести фокус на миниатюру и нажать Enter — изображение поменялось.
- TC4: Отключить JavaScript — в базовой версии должно отображаться хотя бы первое изображение с описанием.
- TC5: Проверить адаптивность на ширине 320–1024 px.
Контрольный список при развёртывании:
- Оптимизировать изображения (WebP + правильные размеры).
- Настроить кэширование на сервере.
- Проверить метаданные (alt, title).
- Прогнать Lighthouse для доступности и производительности.
Частые ошибки и когда решение не подходит
- Если изображения не загружаются, проверьте корректность путей и прав на чтение.
- Для большого количества изображений (сотни) генерация миниатюр на клиенте может быть тяжёлой — используйте серверный индекс или пагинацию.
- Галерея не заменит специализированные решения для сложных требований (например, динамическая подгрузка по API, CDN, тэгирование).
Советы по производительности
- Формат WebP обычно меньше JPEG при равном качестве.
- Используйте responsive srcset для #current-image, чтобы загружать изображение нужного размера.
- Включите CDN и кэширование.
Мини-методология разработки
- Прототип: сделать статическую версию HTML/CSS.
- Добавить минимальную логику JS (нажатия, фокус).
- Провести тесты доступности.
- Оптимизация изображений и загрузки.
- Рефакторинг — поддержка модульности и повторного использования.
Роль-based чек-листы
- Разработчик: проверить работоспособность на современных браузерах, покрыть кейсы клавиатурной навигации.
- Дизайнер: подготовить оптимизированные изображения и состояния (hover, active).
- QA: прогнать тест-кейсы, проверить адаптивность и ошибки сети.
Краткое резюме
Простая галерея — отличный учебный проект. Она сочетает в себе работу с DOM, событиями, CSS-стилизацией и вопросами доступности. Начните с базовой реализации, затем добавляйте улучшения: lazy-loading, адаптивные изображения, keyboard support и категории.
Ключевые шаги: создать структуру HTML, написать стили, динамически сгенерировать миниатюры в JS и прикрутить обработчики событий.
Дополнительные упражнения: реализовать автопроигрывание (slideshow), поддержку touch-свайпов и полноэкранный просмотр.
Факты:
- По умолчанию пример настроен на 10 изображений (image1.jpg…image10.jpg).
Примечание: при переносе в продакшен замените тестовые alt на содержательные описания и оптимизируйте форматы изображений.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone