<Icon />

Никита Мостовой

@xnimorz

130 человек в техдепе

130 человек в техдепе

30 фронтов

130 человек в техдепе

25 команд

30 фронтов

130 человек в техдепе

25 команд

30 фронтов

18+ лет истории

130 человек в техдепе

25 команд

30 фронтов

2 стека

18+ лет истории

130 человек в техдепе

25 команд

30 фронтов

200+ страниц

2 стека

18+ лет истории

Какие иконки

в 2к19?

Какие иконки

в 2к19?

Дисклеймер

Это доклад не о том, как у нас все хорошо

Он не научит делать иконки правильно

Доклад постарается быть полезным на практике

Ссылка на все ссылки в конце доклада присутствует

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

👉

Давайте поговорим?

Почти все решения — ок, имеют свои плюсы и минусы

Почти все решения — ок, имеют свои плюсы и минусы. Выделяется только одно:

Иконочный шрифт?

Скринридеры

Скринридеры

Скринридеры

Их отображение зависит от:

Системы, браузера, настроек системы, настроек видеокарты и  положения луны относительно солнца

Иконочный шрифт?

Please, NO!

Спрайты

<svg width="124" height="16" viewBox="0 0 124 16" 
	 xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="filters" width="16" height="16">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M1 4.667c0-.392.317-.709.708-.709h6a.708.708 0 1 1 0 1.417h-6A.708.708 0 0 1 1 4.667zM12.334 4.667c0-.392.317-.709.708-.709h1.333a.708.708 0 0 1 0 1.417h-1.333a.708.708 0 0 1-.708-.708z"/>
</symbol>
  <use x="0" y="0" xlink:href="#filters" fill="#3d3e42"/>
  <use x="18" y="0" xlink:href="#filters" fill="#fff"/>
</svg>

👍 Разноцветные картинки

👎 Анимации

👍 Кеширование

👎 Количество цветов ограничено размером спрайта и существующих css классов

Спрайты

Inline svg

<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">    
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M1 4.667c0-.392.317-.709.708-.709h6a.708.708 0 1 1 0 1.417h-6A.708.708 0 0 1 1 4.667zM12.334 4.667c0-.392.317-.709.708-.709h1.333a.708.708 0 0 1 0 1.417h-1.333a.708.708 0 0 1-.708-.708z"/>
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M11.625 4.667a1.25 1.25 0 1 0-2.5 0 1.25 1.25 0 0 0 2.5 0zm1.417 0a2.667 2.667 0 1 0-5.334 0 2.667 2.667 0 0 0 5.334 0zM5 11.333c0-.39.317-.708.708-.708h8.667a.708.708 0 0 1 0 1.417H5.708A.708.708 0 0 1 5 11.333z"/>
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M3.708 10.083a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5zm-2.667 1.25a2.667 2.667 0 1 1 5.334 0 2.667 2.667 0 0 1-5.333 0z"/>
</svg>
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">    
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M1 4.667c0-.392.317-.709.708-.709h6a.708.708 0 1 1 0 1.417h-6A.708.708 0 0 1 1 4.667zM12.334 4.667c0-.392.317-.709.708-.709h1.333a.708.708 0 0 1 0 1.417h-1.333a.708.708 0 0 1-.708-.708z"/>
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M11.625 4.667a1.25 1.25 0 1 0-2.5 0 1.25 1.25 0 0 0 2.5 0zm1.417 0a2.667 2.667 0 1 0-5.334 0 2.667 2.667 0 0 0 5.334 0zM5 11.333c0-.39.317-.708.708-.708h8.667a.708.708 0 0 1 0 1.417H5.708A.708.708 0 0 1 5 11.333z"/>
    <path fill="#ff0000" 
          fillRule="evenodd" 
          clipRule="evenodd" d="M3.708 10.083a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5zm-2.667 1.25a2.667 2.667 0 1 1 5.334 0 2.667 2.667 0 0 1-5.333 0z"/>
</svg>

Inline svg

Inline svg

import Filters from "./filters.inline.svg";

ReactDom.render(<Filters width={16} height={16} fill={"#ff0000"} />);

Custom loader

const fs = require("fs");
const { getOptions } = require("loader-utils");

module.exports = function(source) {
  if (this.cacheable) {
    this.cacheable();
  }
  const options = getOptions(this);
  const template = fs.readFileSync(
    options.template, 
    "utf8"
  );

  return template.replace("<icon />", source);
};

Inline svg

👎 Сложнее делать разноцветные картинки

👍 Анимации

👍 Любое количество цветов, размеров — мы никак не ограничены

👎👎👎 Кеширование

Inline svg + use

<svg width="124" height="16" viewBox="0 0 124 16" 
	 xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="filters" width="16" height="16">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M1 4.667c0-.392.317-.709.708-.709h6a.708.708 0 1 1 0 1.417h-6A.708.708 0 0 1 1 4.667zM12.334 4.667c0-.392.317-.709.708-.709h1.333a.708.708 0 0 1 0 1.417h-1.333a.708.708 0 0 1-.708-.708z"/>
</symbol>
  <use x="0" y="0" xlink:href="#filters" fill="#3d3e42"/>
  <use x="18" y="0" xlink:href="#filters" fill="#fff"/>
</svg>

Inline svg + use

<svg xmlns="http://www.w3.org/2000/svg">    
    <symbol width="16" height="16" id="filters">
      <path fill-rule="evenodd" 
            clip-rule="evenodd" d="M1 4.667c0-.392.317-.709.708-.709h6a.708.708 0 1 1 0 1.417h-6A.708.708 0 0 1 1 4.667zM12.334 4.667c0-.392.317-.709.708-.709h1.333a.708.708 0 0 1 0 1.417h-1.333a.708.708 0 0 1-.708-.708z"/>
      <path fill-rule="evenodd" 
            clip-rule="evenodd" d="M11.625 4.667a1.25 1.25 0 1 0-2.5 0 1.25 1.25 0 0 0 2.5 0zm1.417 0a2.667 2.667 0 1 0-5.334 0 2.667 2.667 0 0 0 5.334 0zM5 11.333c0-.39.317-.708.708-.708h8.667a.708.708 0 0 1 0 1.417H5.708A.708.708 0 0 1 5 11.333z"/>
      <path fill-rule="evenodd" 
            clip-rule="evenodd" d="M3.708 10.083a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5zm-2.667 1.25a2.667 2.667 0 1 1 5.334 0 2.667 2.667 0 0 1-5.333 0z"/>
    </symbol>
</svg>

Inline svg + use

function Icon(fill, stroke) {
  return <svg><use fill={fill} stroke={stroke} /></svg>
}

Inline svg + use

👍 Анимации

👎 Кеширование

👍 Любое количество цветов, размеров — мы никак не ограничены

👎 Сложнее делать разноцветные картинки

👎👎 Здравствуй, глобальная область видимости

Новые решения?

CSS-Filters

.red {
  filter: invert(30%) sepia(93%) saturate(7246%) hue-rotate(356deg)
    brightness(102%) contrast(120%);
}

.blue {
  filter: invert(10%) sepia(99%) saturate(4712%) hue-rotate(243deg)
    brightness(108%) contrast(145%);
}

.green {
  filter: invert(54%) sepia(48%) saturate(1714%) hue-rotate(79deg)
    brightness(113%) contrast(126%);
}

CSS-Filters

👍 Анимации

👍 Кеширование

👎 Одноцветные иконки

👎 Браузерная поддержка

CSS-Filters

CSS-Mask

Вместо итогов:

<Icon />

By Nik Mostovoy

Private

<Icon />

More from Nik Mostovoy