Давайте сделаем разноцветные значки с символами SVG и сменными CSS

1657659622 davajte sdelaem raznoczvetnye znachki s simvolami svg i smennymi css

Сара Дайан

rN1zJL4W40roCk80KExLyCSPff859Rzn08Rf
Творческие вещи Кайла Адамса

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

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

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

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

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

TL; DR: эта публикация подробно рассказывает о том, как и почему. Если вы хотите понять весь процесс мышления, читайте дальше. В противном случае вы можете просмотреть окончательный код CodePen.

Настройка символов SVG

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

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

Вы начинаете с добавления встроенного SVG, сокрытия его, завертывания в a <symbol> и идентифицируйте его with атрибут id.

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

Полная разметка SVG включена один раз и скрыта в HTML.

Затем все, что вам нужно сделать, это создать экземпляр значка с помощью a <use>элемент.

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

Это отобразит точную копию оригинального значка SVG.

h50v1hbWZfisticSZPXcpnw8B27gYBQS-bpK

Это! Достаточно хорошо, правда?

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

Важно вспомнить, что xlink:href является устаревшим атрибутом SVG. Даже если большинство браузеров все еще поддерживают это, вы должны использовать href вместо этого. Дело в том, что некоторые браузеры, такие как Safari, не поддерживают ссылку на ресурсы SVG через href атрибут, поэтому вам все равно нужно предоставить 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;}

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

Поначалу у вас может возникнуть соблазн полагаться на конкретность.

// HTML<svg xmlns=" 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но технически говоря они не есть. The <use> элемент естьне местодержатель, который будет заменен вашим определением SVG. яэто рефerence, клонирующее содержимое, на которое указывает into теньow DOM?

Что мы можем тогда сделать? Как мы можем повлиять на соответствующее дочернее содержимое, если указанные дочерние элементы не находятся в DOM?

Сменные CSS в помощь

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

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

Вот проблема: мы хотим пройти другой цвета к другой пути оригинального SVG, но есть только один fill атрибут, который мы можем наследовать.

Знакомьтесь Переменные CSS.

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

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

Все дети из .parent у него будет красный текст.

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

все .child вложены в .parent элементы будут иметь красный текст.

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

// HTML<svg xmlns=" 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;}

И… это работает! ?

YsRaKkdEcVKJNcnPE1ezPjuEt1eVAOmOvNq6

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

// 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 декларация будет работать, поскольку fill атрибуты исходного SVG устанавливаются с неопределенными значениями переменных CSS.

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

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

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

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

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

Дефолт или нет

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

Есть два способа добиться этого: : корень и var() по умолчанию.

: корень

Вы можете определить все свои переменные CSS на :root селектор. Это сохраняет их все в одном месте и позволяет «поделиться» схожими цветами. :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() по умолчанию

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

<svg xmlns=" 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>. Это решает проблему глобального масштаба, которую мы имеем. using :root, но be careful: теперь у вас есть значение по умолчанию, и оно выполняет its работа. В результате вы не можете использовать какingle fill декларация больше для определения монохромных значков. Вам нужно будет назначить цвет каждой переменной CSS, которая используется на значке, один за другим.

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

Насколько это удобно для браузера?

Сменные CSS совместимы с большинством современных браузеров, но, как вы, вероятно, ожидаете, Internet Explorer их не поддерживает совсем. Даже не IE11, и поскольку разработка была прекращена в пользу Edge, нет никаких шансов, что он когда-нибудь достигнет нужной скорости.

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

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

Если вы используете Sass, это можно отвлечь в a @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;  };}

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

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

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

Первоначально опубликовано на frontstuff.io.

Добавить комментарий

Ваш адрес email не будет опубликован.