4 февраля 2026 г. (изменено: 4 февраля 2026 г.)

Канал: @cherkashindev

831

🎭 Про маски

У нас наметился очередной редизайн, и снова всплыла проблема, с которой мы живём уже очень долго — зоопарк иконок.

Если кратко: мы не можем инлайнить SVG или использовать что-нибудь вроде Font Awesome, потому что у пользователя должна быть возможность кастомизировать любую иконку в продукте. А само решение было реализовано лет так 7 назад.

В итоге все иконки подгружаются через background-image, а это значит, что если нужно изменить цвет иконки по ховеру — придётся подгружать новую иконку (спрайты тоже не можем использовать).

Выглядит это примерно вот так:

 
.icon {
 background-image: url(./icon.svg);
 
 &:hover,
 &:focus-visible {
  background-image: url(./icon-hover.svg);
 }
 
 &--active {
  background-image: url(./icon-active.svg);
 }
}

🫠 В 2026 году подход, конечно, ||пиздец|| очень грустный.

Из-за этого каждая иконка дублируется в среднем 3 раза. Представляете, сколько времени занимает добавить новую иконку…

Но, как ни крути, идёт 2026 год, и теперь мы можем использовать CSS-маски — mask-image.

По сути, мы просто указываем цвет фона, а в качестве маски выступает иконка. В итоге получается, что мы её просто перекрашиваем:

 
.icon {
 mask-image: url(./icon.svg);
 background-color: var(--icon-color);
 
 &:hover,
 &:focus-visible {
  background-color: var(--icon-color-hover);
 }
 
 &--active {
  background-color: var(--icon-color-active);
 }
}

В итоге, чтобы поменять цвет иконки, достаточно изменить background-color. А если иконка используется в кнопке, можно воспользоваться currentColor — ровно так же, как и для SVG.

Может, выглядит так себе (хотя вроде норм, да и выбора у нас всё равно нет), зато у подхода есть ряд преимуществ:

  • из коробки работает асинхронная загрузка — не будет проблемы с раздутым бандлом;
  • HTML-разметка не раздувается из-за инлайна SVG;
  • частично решает проблему зоопарка иконок, так как не нужно хранить иконку для каждого цвета.

Ещё по теме:

1️⃣ Если у вас иконки инлайнятся и раздувают бандлы, советую посмотреть доклад
SVG в React: как автоматизировать процесс добавления новых иконок с прошлого «Я 💛 Фронтенд».
Там рассказано, как решили проблему жирного бандла в Centra — с помощью динамического импорта иконок.

2️⃣ А если вам интересно как с зоопарком иконок боролись в VK — посмотрите доклад Зоопарк иконок: упрощаем работу с иконками для дизайна и разработки. Оказывается дизайнеров тоже можно научить пользоваться гитом и сбросить всю ответственность за иконки на них 😅.

Давайте сверимся по иконкам:

  • 👍 — не знал про mask-image;
  • ❤️ — использую библиотечные иконки и нет проблем
  • 🔥 — просто инлайню SVG
👍 11 8 🔥 5