[Перевод] Цветные значки с использованием символов SVG и переменных CSS

внешний интерфейс SVG CSS

Красочные значки с использованием символов SVG и переменных CSS

Прошли те времена, когда изображения и CSS-спрайты использовались для создания веб-иконок. С появлением веб-шрифтов пиктографические шрифты стали решением №1 для отображения значков в ваших веб-проектах.

Шрифты являются векторами, поэтому вам не нужно беспокоиться о разрешении. У них те же свойства CSS, что и у текста, что означает, что вы можете применитьsize,colorа такжеstyle. Вы можете добавлять переходы, специальные эффекты и украшения, такие как повороты, подчеркивания или тени.

Неудивительно, что такие проекты, как Font Awesome, до сих пор загружались только через npm.Более 15 миллионов раз.

Но иконочный шрифт не идеален, поэтому все больше и больше людей используют встроенный SVG. CSS Tricks написалГде иконочные шрифты уступают нативным элементам SVG: резкость, позиционирование или сбои из-за междоменной загрузки, ошибок браузера, блокировщиков рекламы и т. д. Теперь, когда вы можете обойти большинство этих проблем, использование иконочных шрифтов, как правило, является беспроигрышным вариантом.

Однако есть одна вещь, которая абсолютно невозможна с иконочными шрифтами:Многоцветная поддержка. Это может сделать только SVG.

Резюме : этот пост в блоге подробно рассказывает о том, как и почему. Рекомендуем прочитать, если вы хотите понять весь мыслительный процесс. В противном случае вы можете напрямуюCodePenСмотрите окончательный код.

Установить значки флагов SVG

Проблема со встроенным SVG заключается в том, что он может быть очень многословным. Вы определенно не хотите копировать/вставлять все координаты каждый раз, когда используете один и тот же значок. Это было бы очень повторяющимся, трудным для чтения и трудным для обслуживания.

Со значками символов SVG у вас просто есть элемент SVG, и вы можете ссылаться на него везде, где он вам нужен.

Сначала добавьте встроенный SVG, скройте его, а затем используйте<symbol>обернуть егоidОпределите это.

<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
  <symbol id="my-first-icon" viewBox="0 0 20 20">
    <title>my-first-icon</title>
    <path d="..." />
  </symbol>
</svg>

Вся разметка SVG запаковывается за один раз и скрывается в HTML.

Тогда все, что вам нужно сделать, это использовать<use>Метка создает экземпляр значка.

<svg>
  <use xlink:href="#my-first-icon" />
</svg>

Это отобразит копию исходного значка SVG.

**Вот и все! ** Выглядит великолепно, не так ли?

Вы могли заметить это интересноеxlink:hrefСвойства: это связь между вашим экземпляром и исходным SVG.

Следует упомянуть, чтоxlink:hrefявляется устаревшим атрибутом SVG. Хотя большинство браузеров по-прежнему поддерживают,вы должны использовать **href**альтернатива. Теперь вопрос в том, что некоторые браузеры, такие как Safari, не поддерживают использованиеhrefсделать ссылки на ресурсы SVG, поэтому вам все равно нужно предоставитьxlink:hrefопции.

Чтобы быть в безопасности, используйте оба.

добавить немного цвета

в отличие от шрифтов,colorНичего не делает для иконок SVG: вы должны использоватьfillсвойство для определения цвета. Это означает, что они не будут наследовать цвет родительского текста, как шрифты значков, но вы все равно можете стилизовать их в CSS.

// HTML
<svg class="icon">
  <use xlink:href="#my-first-icon" />
</svg>
// CSS
.icon {
  width: 100px;
  height: 100px;
  fill: red;
}

Здесь вы можете создавать разные экземпляры одного и того же значка с разными цветами заливки.

// HTML
<svg class="icon icon-red">
  <use xlink:href="#my-first-icon" />
</svg>
<svg class="icon icon-blue">
  <use xlink:href="#my-first-icon" />
</svg>
// CSS
.icon {
  width: 100px;
  height: 100px;
}
.icon-red {
  fill: red;
}
.icon-blue {
  fill: blue;
}

Это работает, но неполностьюВ соответствии с нашими ожиданиями. Все, что мы сделали до сих пор, можно сделать с помощью обычного иконочного шрифта. Мы хотим, чтобы значки имели разные цвета. мы хотим дать каждомудорожкаЧтобы заполнить его другим цветом без изменения других экземпляров, мы хотим иметь возможность переопределить его, когда это необходимо.

Во-первых, у вас может возникнуть соблазн зависеть от функций.

// HTML
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
  <symbol id="my-first-icon" viewBox="0 0 20 20">
    <title>my-first-icon</title>
    <path class="path1" d="..." />
    <path class="path2" d="..." />
    <path class="path3" d="..." />
  </symbol>
</svg>
<svg class="icon icon-colors">
  <use xlink:href="#my-first-icon" />
</svg>
// CSS
.icon-colors .path1 {
  fill: red;
}
.icon-colors .path2 {
  fill: green;
}
.icon-colors .path3 {
  fill: blue;
}

не работает.

мы пытаемся установить.path1,.path2а также.path3стили, как если бы они были вложены в.icon-colors, но, строго говоря,это неправда.<use>тег не будет заменен вашим определением SVGЗаполнитель. ЭтоЦитироватьскопируйте то, на что он указывает какshadow DOM😱.

**Тогда что нам делать дальше? **Как мы можем культурно воздействовать на ребенка, если он не находится в DOM?

Переменные CSS спасают мир

В CSS,некоторые свойстваНаследуется от родительского элемента к дочернему элементу. Если вы назначаете цвет текста дляbody, весь текст на этой странице будет унаследовать этот цвет до тех пор, пока он не будет переопределен. Родительский элемент не знает о дочернем элементе, нонаследуемыйСтиль продолжает распространяться.

В нашем предыдущем примере мы унаследовализаполнениеАтрибуты. Оглядываясь назад, вы увидите наше заявлениезаполнениеКласс цвета прикреплен кпримерна, не по определению. Вот почему мы можем давать разные цвета каждому отдельному объекту одного и того же определения.

Теперь есть проблема: мы хотим пройтиразныеЦвета исходного SVGразныепути, но только отfillНаследуется в свойствах.

Это требуетCSS-переменные.

Как и любое другое свойство, переменные CSS объявляются в наборе правил. Вы можете использовать любое имя и назначить любое допустимое значение CSS. Затем вы объявляете его как значение для себя или других подсвойств иэто будет унаследовано.

.parent {
  --custom-property: red;
  color: var(--custom-property);
}

все .parent дочерние элементы имеют красный текст.

.parent {
  --custom-property: red;
}
.child {
  color: var(--custom-property);
}

все вложено в .parent на этикетке .child У всех красный текст.

Теперь давайте применим эту концепцию к символам SVG. Мы будем использовать в каждой части определения SVGfillсвойства и установить для них разные переменные CSS. Затем мы назначим им разные цвета.

// HTML
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
  <symbol id="my-first-icon" viewBox="0 0 20 20">
    <title>my-first-icon</title>
    <path fill="var(--color-1)" d="..." />
    <path fill="var(--color-2)" d="..." />
    <path fill="var(--color-3)" d="..." />
  </symbol>
</svg>
<svg class="icon icon-colors">
  <use xlink:href="#my-first-icon" />
</svg>
// CSS
.icon-colors {
  --color-1: #c13127;
  --color-2: #ef5b49;
  --color-3: #cacaea;
}

Потом…вступает в силу🎉!

Теперь, чтобы создавать экземпляры с разными цветовыми схемами, все, что нам нужно сделать, это создать новый класс.

// HTML
<svg class="icon icon-colors-alt">
  <use xlink:href="#my-first-icon" />
</svg>
// CSS
.icon-colors-alt {
  --color-1: brown;
  --color-2: yellow;
  --color-3: pink;
}

Если вы все еще хотите иметь монохромные значки,Вам не нужно повторять один и тот же цвет в каждой переменной CSS.. Вместо этого вы можете объявить одинfillПравило: потому что, если переменная CSS не определена, она вернется к вашемуfillутверждение.

.icon-monochrome {
  fill: grey;
}

твойfillдекларация вступит в силу, потому что исходные SVGfillСвойства определяются неустановленными значениями переменных CSS.

Как мне назвать переменные CSS?

Когда дело доходит до именования в CSS, обычно есть два пути:описыватьилисемантический. Описать означает назвать цветчто: если вы храните#ff0000ты можешь назвать это--red. Семантика означает определение цветакак это будет применяться: если вы используете#ff0000чтобы придать цвет ручке кофейной кружки, вы называете это--cup-handle-color.

Именование описания, возможно, является вашим инстинктом. выглядит более четким, потому что#ff0000Можно использовать не только ручку кофейной чашки. Один--redПеременные CSS можно повторно использовать для других путей к значкам, которые должны быть красного цвета. В конце концов, именно так работает прагматизм в CSS. и являетсяхорошая система.

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

Используйте семантические имена классов, например.--cup-handle-color, что более полезно в данном случае. Когда вы хотите изменить цвет части иконки, вы сразу знаете, что это такое и что нужно переписать. Независимо от того, какой цвет вы назначите, имя класса всегда будет связано.

Дефолт или не дефолт, вот в чем вопрос

Может возникнуть соблазн сделать многоцветную версию значка состоянием по умолчанию. Таким образом, вам не нужно устанавливать дополнительные стили, вы можете просто добавить свои собственные классы, когда это необходимо.

Есть два способа добиться этого::rootа такжеvar() default.

:root

существует:rootВ селекторах вы можете определить все ваши переменные CSS. Это объединит их в одном месте, что позволит вам «поделиться» похожими цветами.:rootИмеет самый низкий приоритет, поэтому может быть легко переопределен.

:root {
  --color-1: red;
  --color-2: green;
  --color-3: blue;
  --color-4: var(--color-1);
}
.icon-colors-alt {
  --color-1: brown;
  --color-2: yellow;
  --color-3: pink;
  --color-4: orange;
}

Однако,У этого метода есть один существенный недостаток. Поначалу может быть немного запутанно отделять определения цветов от соответствующих значков. Когда вы решите переопределить их, вам нужно создать класс с:rootВзад и вперед между селекторами. Но что более важно,Это не позволяет вам связывать ваши переменные CSS, тем самым предотвращая повторное использование одного и того же имени.

В большинстве случаев, когда значок использует только один цвет, я использую--fill-colorимя. Простой, понятный и отлично подходит для всех значков, которым нужен только один цвет. если я должен:rootобъявить все переменные в объявлении, я не буду иметь несколько--fill-color. Я буду вынужден определить--fill-color-1,--fill-color-2или используйте что-то вроде--star-fill-color,--cup-fill-colorпространство имен.

переменная() по умолчанию

ты можешь использовать этоvar()Функция для присвоения переменной CSS свойству, а ее второму параметру может быть присвоено некоторое значение по умолчанию.

<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
  <symbol id="my-first-icon" viewBox="0 0 20 20">
    <title>my-first-icon</title>
    <path fill="var(--color-1, red)" d="..." />
    <path fill="var(--color-2, blue)" d="..." />
    <path fill="var(--color-3, green)" d="..." />
  </symbol>
</svg>

После того, как вы определите финиш--color-1,--color-2а также--color-3Раньше значок использовал<path>Установите значение по умолчанию. Это решается, когда мы используем:rootпроблемы глобальной ассоциации, но будьте осторожны:теперь у вас есть значение по умолчанию, и оно вступит в силу. В результате вы больше не можете использовать одинfillОператор для определения монохромного значка. Вам нужно будет назначить цвет каждой переменной CSS, используемой для этого значка, одну за другой.

Установка значений по умолчанию может быть полезной, но это компромисс. Я предлагаю вам не формировать привычку и делать это только тогда, когда это помогает данному проекту.

How browser-friendly is all that?

Переменные CSS совместимы с большинством современных браузеров., но, как и следовало ожидать, Internet ExplorerполностьюНесовместимо. Поскольку Microsoft прекратила разработку IE11 для поддержки Edge, у IE не будет шансов догнать время в будущем.

Теперь, только потому, что функция несовместима с определенным браузером (и вам нужно адаптироваться), не означает, что вы должны полностью отказаться от нее. В этом случае учтите следующееизящная деградация: Обеспечивает красочные значки для современных браузеров и резервное копирование цветов заполнения для обратных браузеров.

Что вы хотите сделать, так это установить объявление, которое срабатывает только тогда, когда переменные CSS не поддерживаются. Это можно сделать, установив резервный цветfillРеализация свойства: если переменные CSS не поддерживаются, это даже не будет учитываться. Если они не могут быть поддержаны, вашfillЗаявление вступит в силу.

Если вы используете Sass, это можно абстрагировать в@mixin.

@mixin icon-colors($fallback: black) {
  fill: $fallback;
  @content;
}

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

.cup {
  @include icon-colors() {
    --cup-color: red;
    --smoke-color: grey;
  };
}
.cup-alt {
  @include icon-colors(green) {
    --cup-color: green;
    --smoke-color: grey;
  };
}

пройти в миксине@contentПередача переменных CSS также необязательна. Если вы сделаете это снаружи, скомпилированный CSS будет таким же. Но это помогает быть упакованным вместе: вы можете свернуть фрагменты в своем редакторе и визуально различать объявления вместе.

Посмотреть это в другом браузереpen. В последних версиях Firefox, Chrome и Safari последние две чашки имеют красную чашку с серым дымом и синюю чашку с серым дымом. В версиях IE и Edge меньше 15 корпус и дым третьей чашки все красные, а четвертой все синие! ✨

Если вы хотите узнать больше о значках символов SVG (или SVG в целом), ясильныйя предлагаю вам прочитатьВсе, что написано Сарой Суэйдан. Если у вас есть какие-либо вопросы о значках символов CSS, не стесняйтесь спрашивать по адресуTwitterСвяжитесь со мной по.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.