Image sprites в CSS
Optional Advanced только что разобрал !important — редкий флаг override. Эта сессия — другая optional-тема: image sprites. Вы встретите их в старых таблицах стилей и некоторых legacy-наборах иконок. Идея простая: один файл картинки — много иконок; background-position выбирает, какая плитка видна в маленьком окне.
Прямой ответ
CSS image sprite — это один лист-изображение, на котором рядом лежат несколько иконок (или состояний кнопки). Каждый UI-элемент получает фиксированные width и height, тот же background-image и background-position, который сдвигает лист, пока нужная плитка не заполнит коробку. Спрайты сокращали число запросов, когда каждый значок был отдельным HTTP. Для новой работы обычно лучше SVG-иконки, inline SVG или небольшая icon-система — спрайты оставляйте, когда уже есть готовый лист или нужно совпасть с legacy-дизайном.
Зачем спрайты появились
Раньше каждая иконка часто означала ещё один HTTP round-trip. Двадцать крошечных PNG в одном листе — один скачивание и одна запись в кэше. Браузеры рисовали разные «окна» на этот лист через CSS. HTTP/2 и современная сборка ослабили эту боль, а масштабируемые векторные иконки обычно выглядят чётче — но паттерн позиционирования всё ещё полезная грамотность, когда открываете старый CSS.
Три части
Нужно:
- Один лист — например
icons.pngс плитками в ряд или сетку - Коробка —
widthиheightпод одну плитку (часто сdisplay: inline-blockили блочной ссылкой) - Смещение —
background-position, чтобы нужная плитка оказалась под коробкой
background-repeat: no-repeatне даёт листу замостить фон. Вы не грузите отдельный файл на каждую иконку — вы обрезаете по позиции.
Первая плитка на общем листе
Представьте лист, где каждая иконка 32×32 пикселя. Первая — вверху слева. Коробка элемента 32×32, фон начинается с 0 0:
.icon {
display: inline-block;
width: 32px;
height: 32px;
background-image: url("icons.png");
background-repeat: no-repeat;
background-position: 0 0;
}
Коробка работает как viewport. Видна только верхняя левая область 32×32 у icons.png. Остальной лист на месте — просто обрезан размером элемента.
Вторая иконка: сдвиньте лист
Если следующая иконка начинается на 32px правее, сдвиньте фон влево на 32px (отрицательный X). Та же картинка, тот же размер коробки, другое окно:
.icon-home {
display: inline-block;
width: 32px;
height: 32px;
background-image: url("icons.png");
background-repeat: no-repeat;
background-position: 0 0;
}
.icon-search {
display: inline-block;
width: 32px;
height: 32px;
background-image: url("icons.png");
background-repeat: no-repeat;
background-position: -32px 0;
}
Отрицательный X тянет лист влево, и вторая плитка заполняет окно. Второй ряд иконок меняет ещё и Y (например -32px -32px). Меряйте по реальному листу — не угадывайте смещения по памяти.
Hover с другой плитки
Наборы кнопок часто кладут обычное и hover (или active) состояния на один лист. На :hover меняйте только background-position:
.btn-icon {
display: inline-block;
width: 40px;
height: 40px;
background-image: url("btn-sheet.png");
background-repeat: no-repeat;
background-position: 0 0;
}
.btn-icon:hover {
background-position: -40px 0;
}
Второго файла нет — только другой crop. Держите размер коробки стабильным, чтобы контрол не прыгал.
Спокойные привычки для листа
Всегда связывайте лист с явной коробкой и no-repeat. Классы именуйте по роли, а не только по пиксельной арифметике:
.sprite {
display: inline-block;
background-image: url("icons.png");
background-repeat: no-repeat;
}
.sprite--mail {
width: 24px;
height: 24px;
background-position: 0 -48px;
}
.sprite--bell {
width: 24px;
height: 24px;
background-position: -24px -48px;
}
Кратко задокументируйте сетку плиток в комментарии (размер плитки, порядок рядов), чтобы следующий сопровождающий не разбирал «магические числа» методом обратной инженерии.
Спрайты тогда и иконки сейчас
📊 Sprite sheets vs modern icon approaches
| Approach | Best when | Watch out |
|---|---|---|
| CSS image sprite (PNG sheet) | Legacy UI you must keep; one cached sheet already in the project | Raster scales poorly; offsets break if the sheet changes |
| Inline SVG / SVG sprite | Crisp UI icons at any size; easy theming with currentColor |
Slightly more markup or build setup |
| Icon font | Very old stacks that already ship one | Accessibility and ligature quirks; harder to theme than SVG |
| Separate PNG per icon | Rare one-off graphics | Many requests on old HTTP/1 connections |
Real <img> photos |
Content images, galleries, product shots | Not a job for background-position sprites |
Уроки галереи изображений и адаптивных картинок работают с настоящим <img> (flex-миниатюры, object-fit, srcset). Спрайты обычно — декоративный UI-chrome в фоне, а не замена содержательным фото с осмысленным alt.
Для нового UI предпочитайте современные иконки
Для свежего интерфейса начинайте с SVG (inline или небольшая SVG-sprite-система). Острее края, проще цвет, без хрупких пиксельных смещений. К классическому PNG-спрайту идите только если дизайн-пак уже лист, или вы правите CSS, который уже от него зависит.
/* Content photo — use <img>, not a sprite crop */
.hero-photo {
max-width: 100%;
height: auto;
}
/* UI chrome — sprite OK only if the sheet already exists */
.toolbar .icon-save {
width: 16px;
height: 16px;
background-image: url("legacy-toolbar.png");
background-repeat: no-repeat;
background-position: -64px 0;
}
Попробуйте сами
- Набросайте ряд из трёх иконок на бумаге (или откройте реальный спрайт). Запишите ширину плитки (например 32px).
- Создайте
.icon-aсbackground-position: 0 0и подходящей коробкой. - Добавьте
.icon-bс-32px 0(или реальным вторым смещением). - Напишите hover-правило, которое переходит на третью плитку без смены width/height.
- В комментарии одной фразой: почему этот лист ещё живёт (legacy) или почему в следующий раз возьмёте SVG.
Частые ошибки
- Класть контентные фото в спрайт и терять нормальный
alt/ семантику - Забывать width и height, так что виден весь лист или обрезка ломается
- Положительные смещения, когда лист нужно сдвинуть в другую сторону
- Оставлять
background-repeatвключённым — плитки дублируются внутри коробки - Строить новое приложение на PNG-спрайтах по умолчанию вместо SVG
- Копировать смещения из туториала, не измерив свой лист
Кратко
- Спрайт — один лист;
background-positionвыбирает, какая плитка заполняет фиксированную коробку - Исторически это сокращало HTTP-запросы для множества мелких иконок
- Держите
no-repeat, стабильные размеры и имена по роли; документируйте сетку - Для нового UI предпочитайте SVG (или похожее); спрайты — для legacy-листов
- Контентные картинки остаются настоящим
<img>— галереи и адаптивные изображения — другая задача - Optional Advanced дальше: несколько колонок (
multi-column)
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху