Загрузка...

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.

Три части

Нужно:

  1. Один лист — например icons.png с плитками в ряд или сетку
  2. Коробка — width и height под одну плитку (часто с display: inline-block или блочной ссылкой)
  3. Смещение — background-position, чтобы нужная плитка оказалась под коробкой
    background-repeat: no-repeat не даёт листу замостить фон. Вы не грузите отдельный файл на каждую иконку — вы обрезаете по позиции.

Первая плитка на общем листе

Представьте лист, где каждая иконка 32×32 пикселя. Первая — вверху слева. Коробка элемента 32×32, фон начинается с 0 0:

First icon tile from a shared sheet

css
.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). Та же картинка, тот же размер коробки, другое окно:

Second icon with a horizontal offset

css
.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:

Hover state from another sprite tile

css
.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. Классы именуйте по роли, а не только по пиксельной арифметике:

Named sprite roles and no-repeat

css
.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, который уже от него зависит.

When a sprite is the wrong tool

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;
}

Попробуйте сами

  1. Набросайте ряд из трёх иконок на бумаге (или откройте реальный спрайт). Запишите ширину плитки (например 32px).
  2. Создайте .icon-a с background-position: 0 0 и подходящей коробкой.
  3. Добавьте .icon-b с -32px 0 (или реальным вторым смещением).
  4. Напишите hover-правило, которое переходит на третью плитку без смены width/height.
  5. В комментарии одной фразой: почему этот лист ещё живёт (legacy) или почему в следующий раз возьмёте SVG.

Частые ошибки

  • Класть контентные фото в спрайт и терять нормальный alt / семантику
  • Забывать width и height, так что виден весь лист или обрезка ломается
  • Положительные смещения, когда лист нужно сдвинуть в другую сторону
  • Оставлять background-repeat включённым — плитки дублируются внутри коробки
  • Строить новое приложение на PNG-спрайтах по умолчанию вместо SVG
  • Копировать смещения из туториала, не измерив свой лист

Кратко

  • Спрайт — один лист; background-position выбирает, какая плитка заполняет фиксированную коробку
  • Исторически это сокращало HTTP-запросы для множества мелких иконок
  • Держите no-repeat, стабильные размеры и имена по роли; документируйте сетку
  • Для нового UI предпочитайте SVG (или похожее); спрайты — для legacy-листов
  • Контентные картинки остаются настоящим <img> — галереи и адаптивные изображения — другая задача
  • Optional Advanced дальше: несколько колонок (multi-column)

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
7
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху