Иконки — не контент

Иконки — не контент

firefoxic

Большинство материалов для новичков об иконках, учат вставлять иконки инлайном в разметку. Об этом полезно знать, потому что в некоторых случаях может пригодиться на практике. Но ещё полезнее умение удалять иконки из разметки.

Ведь что такое иконки? Это всего лишь дополнительная стилизация интерфейсного текста. Ключевое слово — стилизация. Не место им в разметке, они не несут никакой уникальной и важной информации, а всего лишь стилизуют, как и рамка вокруг кнопки. А это значит, что их лучше перенести в стили.

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

Так мы сможем иконку встраивать в любой контекст: инлайновый, блочный, флексовый, гридовый, да хоть флоатом можно прибить их вправо/влево.

План действий

  1. Если иконки уже заинлайнены, то удаляем их из разметки, убедившись в наличии оригиналов svg в icons/. При отсутствии — снова экспортируем.
  2. У элемента, в котором должна быть вставлена иконка, создаём псевдоэлемент. Обычно ::before, потому что обычно иконка нужна перед текстом, даже если текст доступно скрыт. В очень редких случаях иконка нужна после текста, тогда ::after, хотя и в этом случае можно стилями поставить куда угодно.
  3. Задаём псевдику content: ""; без которого псевдика не будет.
  4. Задаём псевдику нужный display вместо дефолтного inline (если его родитель flex или grid, то необязательно display менять, но лучше перестраховаться и задать block).
  5. Задаём псевдику нужные иконке размеры.
  6. Прописываем путь до иконки с остальными настройками фона.

Пример с сердечком:

.favourite::before {
 content: "";
 display: block;
 width: 20px;
 height: 20px;
 background: ulr("../icons/heart.svg") no-repeat center / contain;
}

Перекраска

Теперь встаёт вопрос, как их перекрашивать при разных состояниях, ведь к фону не пробиться свойством fill.

Тут нам помогут CSS-маски! Принцип их работы как у трафарета, только наоборот:

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

Технически же это всё ещё проще — нам просто надо свойство background заменить на mask, не меняя ничего в его значении. А затем залить в фон нужный нам цвет. И лучше в виде использования кастомного свойства, унаследованного от самого элемента.

.favourite {
 --icon-fill: orange;
}

.favourite::before {
 content: "";
 display: block;
 width: 20px;
 height: 20px;
 mask: ulr("../icons/heart.svg") no-repeat center / contain;
 background: var(--icon-fill);
}

Для перекраски при наведении, просто меняем значение кастомки на элементе,

.favourite:hover {
 --icon-fill: orangered;
}
В Chrome всё ещё требуется префикс -webkit- для масок. Поэтому нам всё ещё нужен autoprefixer.

Один SVG, чтобы править всеми

Ну и сразу можно сделать следующий шаг — использовать фрагменты собираемого плагином стекового спрайта. При этом пути к иконкам надо поправить.

Примеры замены пути:

-url("../icons/heart.svg")
+url("../icons/stack.svg#heart")

Если иконка лежит в поддиректории, то плагин добавляет её префиксом к имени фрагмента, отделяя их по умолчанию подчёркиванием:

-url("../icons/social/telegram.svg")
+url("../icons/stack.svg#social_telegram")

С помощью спрайта мы уменьшаем количество запросов к серверу, вместо десятков мелких файликов грузим одну стопку из всех иконок, и просто обращаемся к нему, запрашивая у него отдельные фрагментики в нужном месте.

Report Page