Размеры в SVG • Про CSS
Управление размерами — тема важная, и чтобы максимально использовать возможности SVG, нужно хорошо понимать как всё работает.
Спецификация.
Вьюпорт
Содержимое SVG-элемента отрисовывается на бесконечном холсте и может быть сколь угодно большого размера, но видимая часть холста соответствует размерам SVG-элемента. Эта область отрисовки называется viewport
(вьюпорт).
SVG позволяет управлять как размерами вьюпорта, так и поведением содержимого относительно него: оно может обрезаться или показываться полностью, может растягиваться с потерей пропорций или стараться уместиться целиком, даже если при этом появляются пустые поля. Этим поведением можно управлять с помощью атрибутов.
Если просто вставить SVG на страницу и не задавать ему никакие размеры, он отобразится размером 300px на 150px, что не поместилось — обрежется:
Ширина и высота
Шириной и высотой элемента можно управлять стандартными свойствами width
и height
:
<svg>
. ..
</svg>
Их можно задавать как атрибутами, так и в CSS:
.mysvg {
width: 350px;
height: 200px;
}
Для размеров в пикселях, задаваемых в атрибутах, единицы измерения можно не указывать.
Потаскайте ползунки, и вы увидите, что изменение ширины и высоты влияет только на вьюпорт и не влияет на содержимое, потому что оно отрисовывается на бесконечном холсте, и неизвестно область какого размера нужно ресайзить.
viewBox
Похожим образом не изменяя размеры содержимого ресайзится iframe
, но в случае с SVG это поведение можно изменить, если определить размеры области с помощью свойства viewBox
:
<svg
viewBox="0 0 180 180">
...
</svg>
Первые два значения — координаты X и Y верхнего левого угла отображаемой области, последние два — ширина и высота. viewBox
задаётся только атрибутом.
Попробуйте теперь изменить размеры, и вы увидите, что содержимое отресайзится, чтобы поместиться целиком.
viewBox
можно использовать, например, для кадрирования изображения, чтобы показывать не всю картинку, а только какую-то её часть:
Это очень простое демо, вот пример посложнее от Sarah Drasner.
Интересно, что если у SVG нет размеров, но задан viewBox
, изображение займёт собой всё доступное пространство:
<svg viewBox="0 0 180 180">
...
</svg>
Это поведение может стать проблемой: если размеры у иконок задаются в стилях, а они не загрузились — страница может превратиться в парад гигантских SVG-иконок. Чтобы этого не произошло, всегда явно задавайте в атрибутах SVG ширину и высоту, их потом легко переопределить в CSS.
preserveAspectRatio
Как мы видели в примере выше, если у SVG заданы размеры и viewBox
, содержимое будет сжиматься и растягиваться с сохранением пропорций, чтобы поместиться целиком, но этим поведением тоже можно управлять — с помощью свойства preserveAspectRatio
(оно задаётся только атрибутом).
Например, с помощью значения none
можно указать, что сохранять пропорции не нужно:
<svg
viewBox="0 0 180 180"
preserveAspectRatio="none"
>
...
</svg>
SVG с viewBox
и preserveAspectRatio='none'
ведёт себя очень похоже на img
: при изменении размеров содержимое масштабируется под размеры вьюпорта не сохраняя пропорции.
none
будет полезно для резиновых фонов:
Остальные значения preserveAspectRatio
состоят из двух частей: первая задаёт выравнивание, вторая — поведение элемента относительно вьюпорта.
Выравнивание задаётся одним значением, определяющим положение по вертикали и по горизонтали, например: xMaxYMin
. Для обеих осей можно задать положение в начале, в середине и в конце:
xMin
, YMin
— в начале оси
xMid
, YMid
— в середине
xMax
, YMax
— в конце
Эти значения можно комбинировать в любых сочетаниях, но порядок должен сохраняться: первым всегда идет значение для X, вторым для Y. Значение для Y всегда пишется с большой буквы.
Поведение элемента определяется второй частью preserveAspectRatio
. Возможные значения:
meet
— содержимое стремится уместиться целиком (как фон с background-size: contain
)
slice
— содержимое заполняет собой всю область видимости (как background-size: cover
: что не поместилось, обрежется)
Важно помнить, что preserveAspectRatio
не работает без viewBox
. viewBox
задает область, которая должна масштабироваться, preserveAspectRatio
определяет как именно она должна это делать.
Также нужно понимать, что preserveAspectRatio
срабатывает, если вьюпорт и вьюбокс имеют разные соотношения сторон. Если соотношения сторон совпадают, и содержимое умещается без полей, preserveAspectRatio
работать не будет (в этом случае в нём просто нет необходимости).
Для использования SVG в качестве иконок достаточно viewBox
и размеров, но если предполагается делать что-то более сложное, имеет смысл разобраться с единицами измерения и системой координат.
Единицы измерения
Внутри SVG можно использовать em
, ex
, px
, pt
, pc
, cm
, mm
, in
, проценты, а также единицы системы координат (user space units). Единицы системы координат соответствуют пикселям, поэтому для значений в пикселях единицы измерения указывать не нужно.
Системы координат
В SVG-документе есть две системы координат:
- Система координат области отрисовки — viewport space.
- Система координат содержимого — user space.
Отсчет системы координат вьюпорта начинается от левого верхнего угла вьюпорта, системы координат содержимого — от левого верхнего края вьюбокса.
По умолчанию система координат содержимого соответствует системе координат вьюпорта, а единицы измерения содержимого — единицам измерения вьюпорта, но при использовании трансформаций или viewBox
масштабируется вся система координат с единицами измерения, то есть пиксели из user space больше не равны пикселям из viewport space.
Поизменяйте размеры элемента и посмотрите что происходит с системой координат содержимого (она показана бирюзовым):
Система координат содержимого начинается из точки 0,0, и если вьюпорт и вьюбокс не совпадают, точка отсчета, как и вся система координат содержимого, будет ездить и масштабироватся вместе с вьюбоксом.
Масштабирование единиц измерения хорошо видно на примере обводки: изначально её толщина равна единице, но при изменении размеров видимая толщина обводки будет изменяться вместе с фигурой:
Если такое поведение нежелательно, это можно исправить с помощью свойства vector-effect
со значением non-scaling-stroke
, оно добавляется к содержимому SVG:
<circle r="60" cx="75" cy="75"
stroke="black" stroke-width="1"
vector-effect="non-scaling-stroke"/>
vector-effect
можно задавать как атрибутом, так и в CSS.
Также новая система координат создается при добавлении трансформаций:
Внутри трансформируемого элемента будет своя своя система координат, отличная от систем координат вьюпорта и вьюбокса.
Тема может выглядеть сложной, но на самом деле, достаточно немного поиграться с кодом, и всё станет понятно. Для лучшего понимания систем координат, размеров и трансформаций в SVG рекомендую демо Сары Суайдан, а также её статьи:
Стилизуем содержимое SVG с помощью CSS
Одним из самых распространенных примеров использования SVG графики являются системы иконок. Для этого используется SVG элемент <use>
, задающий экземпляры (копии) иконок. И при попытке стилизации этих экземпляров возникает куча ограничений. Целью данной статьи как раз является ознакомление с возможными способами обхода этих ограничений при использовании <use>
.
Но перед тем как начать, давайте пробежимся по основам SVG — это постепенно втянет нас в мир use
и теневого DOM, а затем вернемся к CSS. Мы поймем, почему стилизация <use>
является сложной и рассмотрим пути решения этой проблемы.
Быстрый обзор структуры SVG, группировки и связывания (переиспользования) элементов в SVG.
Существует 4 основных элемента, которые используются для определения, задания структуры и связей в SVG коде. Эти элементы делают переиспользование кода проще, сохраняя его чистым и читаемым.
Вот эти элементы: <g>
, <defs>
, <use>
и <symbol>
.
Элемент <g>
(короткое от «group») используется для логической группировки набора связанных графических элементов. С точки зрения графических редакторов, таких как Adobe Illustrator, элемент <g>
имеет ту же функциональность, как и Group Objects. Можно также представлять группу как слой в графическом редакторе.
Группировка элементов полезна, когда мы хотим применить общий стиль, и особенно, если хотим анимировать группу элементов, сохраняя при этом их относительное расположение.
Элемент <defs>
применяется для определения элементов, которые будут использоваться позднее. Определение элементов через <defs>
полезно, когда вы хотите создать своего рода «шаблон», который будет использоваться несколько раз в документе. Элементы, определенные внутри <defs>
не отображаются, пока не будут «вызваны» где-то в документе.
Элемент <symbol>
сочетает в себе преимущества и <defs>
и <g>
, т.к. может использоваться в качестве группировки элементов, определяющих шаблон, на который можно ссылаться из любого места документа. В отличие от <defs>
, <symbol>
как правило, не используются для определения шаблонов, а в основном используется, чтобы определить символы (например иконки), на которые имеются ссылки по всему документу.
Элемент <symbol>
имеет важное преимущество: он принимает атрибут viewBox
, который позволяет масштабироваться внутри любого вьюпорта, в котором происходит отрисовка.
Элемент <use>
используется для ссылки на другие элементы, определенные где-то в документе. Он позволяет повторно использовать существующие элементы, давая вам возможность, аналогичную копированию-вставке в графическом редакторе. Он может применяться для переиспользования как отдельного элемента, так и группы, заданной через <g>
, <defs>
или <symbol>
.
Для использования элемента передаем ссылку на него внутри xlink:href
атрибута, а также устанавливаем x
и y
. Вы можете применять стили к use
, и эти стили каскадно применятся к содержимому use
элемента.
Но откуда берется содержимое <use>
? Где происходит клонирование? И как CSS работает с этим содержимым?
Прежде чем отвечать на эти вопросы, стоит упомянуть несколько статей для лучшего понимания этих элементов и атрибута viewBox
, который использует <symbol>
:
SVG <use> и теневой DOM
Когда мы ссылаемся на элемент с помощью <use>
, код примерно такой:
<symbol viewBox="0 0 30 30">
<!-- icon content / shapes here -->
</symbol>
<use xlink:href="#my-icon" x="100" y="300" />
На экране отобразится иконка, которая определена внутри элемента <symbol>
, но это скорее содержимое <use>
, коротое является дубликатом содержимого <symbol>
.
Но элемент <use>
одиночный — внутри него нет никакого содержимого, но где тогда происходит дублирование содержимого <symbol>
?
Ответ — теневой DOM.
Что такое теневой DOM?
Теневой DOM подобен обычному DOM за исключением того, что узлы (nodes) в теневом DOM принадлежат не основному дереву документа, а конкретному его фрагменту. Это дает программистам возможность инкапсуляции, задания скриптов и стилей при создании модульных компонентов. Если вы когда-то использовали HTML5 элемент <video>
и задумывались, где спрятан код его элементов управления — значит вы уже сталкивались с теневым DOM.
В примере с <use>
, контент связанного элемента дублируется во фрагмент документа, который располагается в <use>
. В данном случае <use>
называется теневым хостом (Shadow Host).
Итак, содержимое <use>
(клон или копия любого ссылающегося элемента) присутствует в теневом фрагменте документа.
Другими словами, содержимое там есть, но его не видно. Оно такое же как и содержимое обычного DOM, но вместо того, чтобы быть доступно на высоком уровне («high-level» DOM), оно копируется в определенный фрагмент документа в <use>
.
Возможно сейчас вы задумались, можно ли увидеть эти скрытые части документа? Да, это возможно с помощью инструментов разработчика Chrome. (В Firefox пока нельзя). Итак, для того чтобы включить просмотр теневого DOM, нужно в основных настройках (вкладка General) активировать соответствующий флаг (Show user agent shadow DOM). Настройки открываются при клике по значку шестеренки. Подробнее об этом можно почитать здесь.
После того, как мы включили показ теневого DOM, на панели Elements можно увидеть дублированные элементы в виде обычных DOM элементов. На следующем изображении показан пример <use>
элемента, ссылающегося на содержимое <symbol>
. Обратите внимание на #shadow-root и его содержимое.
С помошью инструментов разработчика Chrome, вы можете проинспектировать содержимое элемента <use> внутри теневого DOM.
Глядя на этот код, вы можете убедиться, что теневой DOM очень похож на обычный DOM, за исключением разного поведения при обработке CSS и JavaScript из главного документа. Есть еще и другие отличия, но здесь о них говорить не будем, т.к. тема слишком обширная. Если хотите узнать больше об этом, рекомендую следующие статьи:
Лично я, учитывая насколько ограничены мои взаимодействия с теневым DOM, думаю о нем как об обычном DOM кроме случаев обработки стилей через CSS (и JavaScript). Вся суть элемента <use>
заключается в возможности создания различных «копий» элемента, но во многих случаях нам нужно стилизовать каждую копию по-разному. Например представьте логотип в двух стилях (инвертированные цветовые темы), или разноцветные иконки, каждая из которых имеет свою цветовую тему. И конечно мы ожидаем, что сможем сделать это с помощью CSS.
Но как мы уже говорили ранее, содержимое теневого DOM нельзя стилизовать так же, как для обычного. Но тогда как нам быть? Мы не можем написать что-то вроде:
use path#line {
stroke: #009966;
}
потому что не имеем доступа обычных CSS селекторов к теневому DOM.
Есть несколько специальных селекторов, которые позволяют «проникнуть» в теневой DOM, чтобы применить стили к узлам внутри него, но эти селекторы не только имеют плохую поддержку, но и очень ограничены по сравнению с обычными CSS селекторами. Кроме того, нам хочется более простого способа для стилизации содержимого <use>
без необходимости «пачкать руки» в специфических особенностях теневого DOM. Мы просто хотим использовать CSS и SVG.
Чтобы этого добиться и получить немного больше контроля над процессом стилизации, мы должны думать под другим углом. И начнем с возможностей наследования в CSS.
Каскадные стили
В SVG элементы могут быть стилизованы тремя способами: внешние CSS стили (внешний файл), внутренние стили (элементы <style>
) и встроенные стили (в виде атрибута style
). Для нас имеет смысл то, как происходит применение стилей к элементам.
Помимо CSS свойств, SVG элементы можно стилизовать с помощью т.н. атрибутов представления. Атрибуты представления — это сокращенная запись задания CSS свойств элементу. Считайте их специальными стилевыми свойствами. По сути это то же самое, но менее ожидаемым образом.
В следующем куске кода, который просто отображает розовый круг с желтой обводкой, stroke
, stroke-width
и fill
являются атрибутами предстваления.
<svg viewBox="0 0 100 100">
<circle fill="deepPink" stroke="yellow" stroke-width="5" cx="50" cy="50" r="10"></circle>
</svg>
Множество всех CSS свойств может устанавличаться через SVG атрибутамы, и наоборот. Но не все CSS свойства могут быть указаны у SVG элемента как атрибуты представления и не все атрибуты представления, доступные в SVG, могут быть указаны через CSS.
Спецификация SVG перечисляет, какие SVG атрибуты могут быть установлены через CSS свойства. Некоторые из этих атрибутов доступны как CSS свойства (например opacity
и transform
), а некоторые — нет (fill
, stroke
, stroke-width
).
В SVG 2 этот список пополнился x
, y
, width
, height
, cx
, cy
и несколькими другими атрибутами представления, которые невозможно было установить через CSS в SVG 1.1. Новый список атрибутов в спецификации SVG 2.
Если вы похожи на меня, то ожидаете, что у атрибутов представления больший приоритет, чем у других объявлений стилей. Я подразумеваю, что внешние стили переопределяются внутренними, внутренние — встроенными (inline). Т.о. наиболее «внутренние» стили имеют больший приоритет, и когда свойство указывается в атрибуте, оно более значимое и переопределяет все остальные объявления. Однако это не так.
На самом деле атрибуты представления имеют низкий приоритет, ниже внешних, внутренних и встроенных стилей. Они могут переопределить наследуемые элементом стили, и сами переопределяются любыми другими объявлениями стилей.
Отлично, теперь когда с этим все прояснилось, давайте вернемся к элементу <use>
и его содержимому.
Теперь мы в курсе, что не можем задать стили внутри элемента <use>
при помощи CSS селекторов. Также мы знаем, что стили, примененные к элементу <use>
, будут унаследованы всеми его потомками (которые внутри теневого DOM).
Итак, первой попыткой изменить цвет заливки элемента внутри <use>
будет применение этого стиля непосредственно на <use>
и пусть наследование делает свое дело.
Однако это вызовет две проблемы:
- Цвет заливки будет наследоваться всеми потомками
<use>
, даже теми, которые не нужно стилиизовать. (Если внутри<use>
только один элемент, то это не проблема) - Если вы экспортируете SVG из графического редактора или получили его от дизайнера, и по какой-то причине не можете отредактировать SVG код, вероятно вы остановитесь на атрибутах представления, которые в свою очередь переопределят любые стили, применяемые к
<use>
. И если вы определяете стили на<use>
, вы хотите, чтобы они были унаследованы всеми потомками, т.о. атрибуты представления вызвали бы неудобство.
И даже если у вас есть доступ к коду SVG и вы можете избавиться от атрибутов представления, настоятельно рекомендую этого не делать, потому что:
- Удаление атрибутов, используемых для установки определенных свойств, сбросит эти свойства в значения браузера по умолчанию — в большинстве случаев это черная заливка и обводка (если говорить о цвете)
- Сбрасывая все значения, вы вынуждаете себя определять стили для всего набора свойств.
- Первоначально доступные атрибуты представления являются отличным механизмом запасного варианта, когда устанавливаемые вами внешние стили по какой-либо причине не применились. Если CSS файл не сможет подгрузиться, у вашей иконки по крайней мере будут хорошие стили по умолчанию. Я настоятельно рекомендую их сохранять.
Хорошо, теперь у нас есть эти атрибуты, но предположим, что мы хотим стилизовать каждый экземпляр иконки по-разному.
Давайте начнем с простого примера, а затем перейдем к более сложным.
Переопределение атрибутов представления через CSS
Атрибуты представления переопределяются другими объявленными стилями. Мы можем этим воспользоваться, чтобы внешние стили переопределяли свойства наследуемых значений элемента <use>
.
Используя ключевое слово inherit в CSS, можно сделать это довольно просто. Посмотрите на следующий пример, в котором имеется иконка мороженого, сделанная с помощью одной линии. Автор иконки Erin Agnolu из проекта Noun. Пусть мы хотим изменить цвет единственной линии для разных экземпляров.
<svg>
<symbol>
<path fill="#000" d="M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844 c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442 c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933 c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04 c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929 C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907 c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48 c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631 c0,1.684-0.914,3.148-2.266,3.958h35.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z M50.01,86.723L27.73,49.13h54.541L50.01,86.723z"/>
</symbol>
</svg>
Содержание иконки (path
) определяется внутри элемента <symbol>
. Это означает, что они не будут отображаться на холсте.
Затем мы рендерим несколько экземпляров иконки с помощью <use>
.
<svg viewBox="0 0 100 125">
<use xlink:href="#ic" x="0" y="0" />
</svg>
<svg viewBox="0 0 100 125">
<use xlink:href="#ic" x="0" y="0" />
</svg>
И устанавливаем ширину и высоту через CSS. Я использую такие же размеры как у viewBox
, но они не обязательно должны быть такими же. Однако, чтобы избежать избытка пустого места внутри SVG, убедитесь, что пропорции сохранены.
.icon {
width: 100px;
height: 125px;
}
В итоге получается следующее:
Обратите внимание на черные границы, т.о. можно видеть границы каждого SVG и удостовериться, что в первом случае (где мы лишь определили иконку) ничего не рандерится. Итак, SVG документ все равно будет отображаться на странице, даже если в нем нечего показывать. Чтобы этого избежать, скрываем первый SVG (display: none
). Если этот элемент не скрывать, по умолчанию он будет показываться на странице с размерами 300x150px, так что в итоге вы получите белую область на странице.
Теперь попробуем изменить цвет заливки для разных экземпляров:
use.ic-1 {
fill: skyblue;
}
use.ic-2 {
fill: #FDC646;
}
Цвет все еще не изменился, т.к. он наследуется от элемента path (fill="#000"
). Поэтому для path
наследуем цвет заливки:
svg path {
fill: inherit;
}
И вуаля! Теперь цвет, указанный для каждого <use>
, применяется для path
. Посмотрите демо, поиграйтесь с цветами, создайте больше экземпляров:
Эта техника полезна, когда нужно применить внутри <use>
наследуемые от главного элемента стили. Но в большинстве случаев требуется не совсем то. Поэтому перейдем к другим примерам.
Стилизация соедержимого <use> с помощью CSS свойства all
Некоторое время назад я работала над иконкой, на которую ссылалась через <use>
, и хотела, чтобы один из элементов внутри наследовал все стили (fill
, stroke
, stroke-fill
, opacity
и даже transform
) от <use>
. В общем я хотела управлять всеми этими атрибуатми из CSS, при этом оставляя атрибуты представления в разметке как запасной вариант.
Оказавшись в такой же ситуации, вы вероятно напишете в CSS:
path#myPath {
fill: inherit;
stroke: inherit;
stroke-width: inherit;
transform: inherit;
/* ... */
}
Видно, что нужно устанавливать все свойства в inherit
. К счастью, нас выручит CSS свойство all
. Я уже писала о нем в заметке, но стоит еще раз упомянуть в данном контексте.
Используя свойство all
, мы можем переписать код следующим образом:
path#myPath {
all: inherit;
}
Это отлично работает во всех браузерах, которые поддерживают данное свойство (посмотрите упомянутую заметку), однако есть важное замечание: это объявление установит буквально все свойства в значение inherit, даже те, которые вам не хочется. Поэтому применять all — это лишь чрезвычайная мера, особенно полезная, если вы хотите «заложить основу» элемента и можете управлять свойствами через CSS. Если вы будете использовать такое объявление, не определив конкретные значения для всех свойств в CSS, они каскадно будут искать родительские значение, и в большинстве случаев применят стили браузера по умолчанию.
Обратите внимание, что это затронет атрибуты, которые могут быть установлены через CSS, не SVG атрибуты. Т.о. если атрибут может быть установлен через CSS, он будет искать значение родителя, а иначе — не будет.
Мы в состоянии заставить атрибуты представления наследоваться от стилей элемента <use>
. Но что если наша иконка содержит несколько элементов, и мы не хотим, чтобы все элементы наследовали свойства от <use>
? Что делать, если мы хотим применить разные цвета для разных элементов внутри <use>
? Установка одного стиля к use
больше не поможет, нужно что-то еще, чтобы помочь нам задать нужные цвета нужным элементам…
Использование CSS-переменной currentColor для стилизации содержимого <use>
Использовуя CSS-переменную currentColor в сочетании с описанной техникой, можно указать два разных цвета на элементе вместо одного. Fabrice Weinberg описал этот способ в своем Codepen блоге около года назад.
Идея заключается в том, чтобы применить к <use>
оба свойства (fill
и color
). Давайте сразу перейдем к примеру кода, чтобы увидеть как это работает.
Предположим, что мы хотим стилизовать простой логотип Codrops, используя два цвета — один для передней капельки, второй для задней — и сделаем несколько экземпляров.
Для начала сделаем разметку для этого примера: должен быть <symbol>
, содержащий определение нашей иконки и 3 экземпляра <use>
.
<svg>
<symbol viewBox="0 0 23 30">
<path fill="#aaa" d="M22.63,18.261c-0.398-3.044-2.608-6.61-4.072-9.359c-1.74-3.271-3.492-5.994-5.089-8.62l0,0 c-1.599,2.623-3.75,6.117-5.487,9.385c0.391,0.718,0.495,1.011,0.889,1.816c0.143,0.294,0.535,1.111,0.696,1.43 c0.062-0.114,0.582-1.052,0.643-1.162c0.278-0.506,0.54-0.981,0.791-1.451c0.823-1.547,1.649-2.971,2.469-4.33 c0.817,1.359,1.646,2.783,2.468,4.33c0.249,0.47,0.513,0.946,0.791,1.453c1.203,2.187,2.698,4.906,2.96,6.895 c0.292,2.237-0.259,4.312-1.556,5.839c-1.171,1.376-2.824,2.179-4.663,2.263c-1.841-0.084-3.493-0.887-4.665-2.263 c-0.16-0.192-0.311-0.391-0.448-0.599c-0.543,0.221-1.127,0.346-1.735,0.365c-0.56-0.019-1.095-0.127-1.599-0.313 c1.448,3.406,4.667,5.66,8.447,5.78C19.086,29.537,23.469,24.645,22.63,18.261z"/>
<path fill="#ddd" d="M6.177,11.659c0.212,0.367,0.424,0.747,0.635,1.136c0.164,0.303,0.333,0.606,0.512,0.927 c0.683,1.225,1.618,2.898,1.755,3.937c0.144,1.073-0.111,2.056-0.716,2.769c-0.543,0.641-1.315,1.014-2.186,1.067 c-0.87-0.054-1.643-0.43-2.186-1.067c-0.604-0.713-0.858-1.695-0.715-2.771c0.137-1.036,1.072-2.712,1.755-3.936 c0.18-0.32,0.349-0.623,0.513-0.927C5.752,12.404,5.964,12.026,6.177,11.659 M6.177,5.966L6.177,5.966 c-1.02,1.649-2.138,3.363-3.247,5.419c-0.932,1.728-2.344,3.967-2.598,5.88c-0.535,4.014,2.261,7.09,5.846,7.203 c3.583-0.113,6.379-3.189,5.845-7.203c-0.255-1.912-1.666-4.152-2.598-5.88C8.314,9.329,7.196,7.617,6.177,5.966L6.177,5.966z"/>
</symbol>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
Если мы установим fill
на элемент <use>
, этот цвет будет применяться к обоим path
, и получатся две одноцветные капельки — это не то, чего мы хотим.
Здесь мы будем использовать currentColor
для разделения цветов. Вставляем currentColor
в том месте, где хотим применить другой цвет. Это должно быть в определении нашей иконки, т.е. внутри элемента <symbol>
. Получаем следующий код:
<svg>
<symbol viewBox="0 0 23 30">
<path fill="#aaa" d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
Далее мы должны удалить атрибут представления fill
для второй капельки, позволив применить цвет заливки use
, без использования техники наследования.
Если мы будем использовать ключевое слово inherit
для того, чтобы атрибуты представления унаследовали свои значения от <use>
, тогда оба path
будут иметь одинаковые значения цвета, и мы не увидим никакого эффекта от использования currentColor
. В нашем случае нужно удалить атрибут, который хотим устанавливать через CSS, и оставить только один path со значением fill="currentColor"
.
<svg>
<symbol viewBox="0 0 23 30">
<path d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
Теперь, используя свойства fill
и color
, мы можем стилизовать капельки:
.codrops-1 {
fill: #4BC0A5;
color: #A4DFD1;
}
.codrops-2 {
fill: #0099CC;
color: #7FCBE5;
}
.codrops-3 {
fill: #5F5EC0;
color: #AEAFDD;
}
Каждый элемент <use>
получает свои значения fill
и color
. Для каждого цвет fill
наследуется от первого path
, который не имеет атрибута fill
, и значение свойства color используется в качестве атрибута fill
для второго path
.
Вот результат:
Эта двухцветная техника весьма полезна для простых двухцветных логотипов. В своей статье Fabrice делает три разных варианта логотипа Sass, изменяя цвет текста и цвет фона.
На сегодня currentColor
— это единственная доступная переменная в CSS. Однако, если бы у нас было больше переменных, мы бы смогли передать больше значений в содержимое <use>
. Amelia Bellamy-Royds представляла эту концепцию в записи своего Codepen блога около года назад. Давайте посмотрим, как это работает.
Будущее: стилизация содержимого <use> с помощью кастомных CSS свойств (CSS переменных)
Используя собственные CSS свойства (CSS переменные), вы можете стилизовать содержимое <use>
без необходимости переопределения значений атрибутов представления.
Как сказано в MDN, CSS переменные — это объекты, определяемые авторами или пользователями на веб страницах для того, чтобы хранить определенные значения всюду в документе. Они устанавливаются, используя кастомные свойства и для получаения доступа используется var()
. Они очень похожи на переменные CSS препроцессоров (типа Sass), но более гибкие и могут делать вещи, которые переменные препроцессора не умеют.
У переменных, будь то CSS переменные или переменные препроцессора, есть много примеров использования, но именно изменение цветов является наиболее распространенным примером. И здесь мы рассмотрим, как это может быть применено для SVG.
Мы рассмотрим одно изображение, определенное в <symbol>
и один элемент <use>
, однако все описанное может быть применено и для множества элементов <use>
.
Предположим, у нас есть иллюстрация милого робота-хипстера (от Freepik).
Код разметки для этого робота такой:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
Мы не собираемся использовать CSS переменные как значения fill
для каждого path; вместо этого, мы собираемся задать значение fill
через CSS, и при этом храним атрибуты fill
в разметке. Эти атрибуты будут использованы в качестве запасного варианта для браузеров, не поддерживающих CSS переменные. Поэтому в таких браузерах изображение будет показываться с первоначальными цветами.
С добавлением переменных, получается такой код:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
Т.к. встроенные стили переопределяют атрибуты представления, браузеры, поддерживающие CSS переменные, будут использовать эти переменные в качестве цвета заливки. А браузеры, не имеющие поддержки CSS переменных, будут вместо этого использовать значение атрибута fill
.
Далее мы должны определить значения переменных в CSS. Для начала покажем изобрачение с помощью <use>
:
<svg>
<use xlink:href="#robot" />
</svg>
Затем переменные должны быть определены на элементе <use>
, чтобы они каскадом перешли в его содержимое. Цвета, которые мы выберем для переменных, составят цветовую схему нашей иллюстрации. Для робота имелось три основных цвета: которые я назову primary, secondary и tertiary.
#robot-1 {
--primary-color: #0099CC;
--secondary-color: #FFDF34;
--tertiary-color: #333;
}
После применения вышеупомянутых цветов для переменных, получается немного другой робот:
Вы можете сделать много экземпляров, поиграться с цветами и реализовать несколько тем.
Мы упомянули, что браузеры, не поддерживающие CSS переменные, в качестве запасного варианта используют стили из атрибутов представления; браузеры, имеющие поддержку, будут использовать именно переменные вместо атрибутов. Отлично. Но что произойдет, если браузер поддерживает CSS переменные, но автор забывает указать значение переменной, или указано неверное значение?
Для нашего робота мы определили 3 переменные, и несколько элементов осталось без определения. Если мы запустим текущий код в браузере, который поддерживает CSS переменные (в настоящее время только Firefox), и удалите объявление переменной из CSS, вот что получится:
Если значения переменных не установлены или они неверные, браузер будет использовать цвета по умолчанию, и обычно это черный цвет для заливки и обводки в SVG.
Способом избежать этого является указание других «запасных» цветов для браузеров. Синтаксис CSS переменных подразумевает использование «запасных» цветов. Они указываются в var()
вторым аргументом. Т.о. код изменится:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
Вот и все. Для любой переменной, которой не удается найти установленное значение, браузер применит запасной цвет, указанный в разметке. Замечательно.
Используя эту технику, вы можете ссылаться на робота из любого места на странице с помощью элемента <use>
, и для каждого нового экземпляра задавать цвета через CSS, тем самым создавая различные цветовые темы.
Можете поиграться с демо, создать несколько экземпляров робота, менять значение переменных. Но только удостоверьтесь, что используете Firefox, потому что это пока что единственный браузер, который поддерживает CSS переменные.
Если вы смотрите демо в Firefox, то должны видеть синюю + желтую версию робота, как определяется в CSS переменных. Если смотрите в Chrome — зеленую версию, вступает в игру запасной вариант. Попробуйте также удалить объявление CSS переменных и посмотреть, как работает запасной вариант в Firefox.
Заключение
Уф. Многовато получилось.
Используя преимущества CSS каскадирования, стилизация содержимого <use>
(в теневом DOM) может стать проще. А с помощью CSS переменных (будь то единственный currentColor
или кастомные переменные) мы можем проникнуть внутрь теневого DOM и кастомизировать графику так, как нам захочется, при этом обеспечивая хороший запасной вариант, когда что-то пойдет не так.
Лично я невероятно поражена связкой CSS переменные + SVG. Мне нравятся их возможности, при том что имеется отличный запасной механизм. Как уже говорилось ранее, пока поддержка реализована только в Firefox, но мы можем добиться более широкой поддержки браузерами, например проголосовав на форуме MS Edge.
В будущем мы даже можем получить другие способы стилизации содержимого <use>
, уже есть дискуссии по поводу использования CSS переменных а качестве SVG параметров. Т.о. хотя эта статья оказалась длинной, все же не затронула все, что нужно знать по этой теме.
Инспектирование содержимого <use>
элементов было одним из частых вопросов, вызывающих недопонимание. На эту тему существует много статей, но здесь не об этом.
Надеюсь статья вам понравилась и вы нашли что-то полезное для себя.
Спасибо за прочтение!
SVG: Используем стили CSS
Немного о CSS внутри SVG-документа мы упомянули в статье о структуре файла.
Продолжим изучение темы при использовании стандартных стилей CSS.
Фон в SVG является прозрачным. Можно через CSS указать нужный фон.
svg {
background: #fcedd6;
}
Можно вынести свойства в отдельный блок style в html-документе.
<style>
#sample rect {
fill: yellow;
stroke: green;
stroke-width: 4;
transition: all 350ms;
}
#sample rect:hover {
fill: magenta;
}
</style>
<svg id="sample" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
<rect x="4" y="4" />
</svg>
При наведении мыши цвет изменится (мы определили :hover).
Можно сослаться на внешний CSS-файл.
<?xml-stylesheet type="text/css" href="style.css"?>
Элементы SVG могут быть сгруппированы с помощью элемента <g>, который можно использовать как контейнер с общими стилям для всех элементов в группе:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
<g style="fill:red; stroke:blue; stroke-width:4; fill-opacity: 0.5;">
<rect x="90" y="5"/>
<circle cx="70" cy="50" r="44"/>
</g>
</svg>
Рассмотрим практичный. Создадим цветочный орнамент.
Измените ширину браузера, чтобы увидеть изменения в SVG-картинке
Фигура состоит из множества элементов path, которым можно присвоить идентификатор id. А затем мы можем настроить нужный элемент через CSS (как внутри SVG, так и в HTML-документе).
Далее, мы можем дать другой цвет нужному элементу, например, нижнему левому фрагменту.
path#left-outer-flourish {
opacity: 0.6;
fill: #f00;
}
Также можем управлять видимостью элементов, используя медиа-запросы.
svg#flourish path {
transition: .6s opacity;
}
@media screen and (max-width: 900px) {
path#right-outer-flourish, path#left-outer-flourish {
opacity: 0;
}
}
Если теперь постепенно уменьшать ширину окна браузера, то можно заметить, как исчезают отдельные элементы орнамента.
Источник: the new code – Create Adaptive SVG Illustrations With CSS
Дополнительное чтение
Управление контурами через CSS
Вернуться в раздел SVG
Реклама
SVG. Работаем с текстом
Выводим текст
Текст задаётся с помощью тега text. Основные атрибуты — x и y. Нужно не забывать указывать базовую линию для текста, за которую отвечает атрибут y. Если её не указать, то по умолчанию она окажется в точке с координатой 0, и текст станет невидимым, так как он рисуется над базовой линией. Значение атрибута должно быть больше размера шрифта. Размер viewBox также должно быть по крайней мере равен размеру атрибута. Атрибут font-sizeзадаёт размер шрифта в пикселях относительно viewBox. Текст при этом адаптируется к размерам страницы. Также доступны и другие атрибуты.
Текст из SVG можно выделять и копировать. Текст, помещаемый в SVG-документ, индексируется поисковыми системами.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 80">
<text y="50" font-size="32" font-weight="bold"
font-family="Avenir, Helvetica, sans-serif">
Этот кот в SVG
</text>
</svg>
Этот кот в SVG
Нужно следить за размерами viewBox, чтобы длинный текст уместился в контейнере.
Как и в HTML, лишние пробелы игнорируются.
Чтобы сдвинуть текст по горизонтали, можно использовать атрибут x в text. Если атрибут не указан, то используется значение по умолчанию 0.
Атрибуты
- direction — Направление текста. В некоторых языках (например, в арабском) принято писать текст справа налево. Для задания написания справа налево необходимо дополнительно включать атрибут unicode-bidi. Возможные значения: rtl | ltr (по умолчанию)
- dominant-baseline — Выравнивание текста относительно горизонтальной линии. Возможные значения: auto (по умолчанию) | hanging | mathematical
- fill — Цвет текста. Поддерживаются именованные значения, а также RGB-код в десятичной и шестнадцатеричной формах. Значение по умолчанию — black
- font-family — Шрифт текста. Все шрифты, доступные на компьютере. При отсутствии заданного шрифта будет использован подобный (например, при отсутствии шрифта Arial будет использован Arial Bold). Значение по умолчанию — Arial
- font-size — Размер шрифта. Значение по умолчанию 12 пт.
- font-size-adjust — Значение по умолчанию — none
- font-stretch — Сжатие и растяжение текста. Возможные значения: normal (по умолчанию) | wider | narrower | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded
- font-style — Начертание текста. Возможные значения: normal (по умолчанию) | italic | oblique
- font-weight — Вес шрифта. От 100 до 900 — Эти значения формируют упорядоченную последовательность, где каждый номер обозначает вес, который темнее своего предшественника. normal — то же, что «400». bold — то же, что «700». bolder — Определяет вес шрифта, более темный, чем наследуемый. Если такого веса нет, результатом будет более «темное» числовое значение (а шрифт не изменяется), если только наследуемое значение не «900», в этом случае результат будет также «900». lighter — Определяет вес шрифта, назначаемый шрифту, который светлее, чем наследуемый. Если такого веса нет, результатом будет более «светлое» числовое значение (а шрифт не изменяется), если только наследуемое значение не «100», в этом случае результат будет также «100». Возможные значения: normal (по умолчанию) | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
- glyph-orientation-horizontal — Горизонтальная ориентация символов. Возможен выбор из фиксированного диапазона значений угла. Возможные значения: 0 | 90 | 180 | 270 (и значения со знаком минус). По умолчанию — auto или 0
- glyph-orientation-vertical — Вертикальная ориентация символов. Возможен выбор из фиксированного диапазона значений угла. Возможные значения: 0 | 90 | 180 | 270 (И значения со знаком минус). По умолчанию — auto или 0
- kerning — Интервал между буквами. Возможные значения: auto (по умолчанию) | число
- letter-spacing — Интервал между буквами. Возможные значения: normal | число
- text-anchor — Выравнивание текста относительно начала строки. Возможные значения: start (по умолчанию), middle, end
- text-decoration — Подчеркивание, надчеркивание, перечеркивание текста. Возможные значения: none (по умолчанию) | underline | overline | line-through
- unicode-bidi — Для работы атрибута direction со значением ltr необходимо наличие в коде свойства unicode-bidi со значением embed или override. Возможные значения: normal (по умолчанию) | embed | bidi-override
- word-spacing — Интервал между словами. Возможные значения: normal (по умолчанию) | число
- writing-mode — Устанавливает расположение текстового фрагмента как единого целого относительно исходной точки. Возможные значения, например, слева направо — сверху вниз ( left to right top to bottom ) не изменяют порядок самих букв в словах. Возможные значения: lr-tb (по умолчанию) | rl-tb | tb-rl | lr | rl | tb
- x — Абсцисса верхней левой точки текстового блока. Значение по умолчанию: 0
- y — Ордината верхней левой точки текстового блока. Значение по умолчанию: 0
Стилизация
Текст может быть стилизован с помощью свойств CSS, таких как font-weight, font-style, text-decoration, text-transform и т.д.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<text x="0" y="15">Подчеркнутый кот средствами SVG</text>
</svg>
Подчеркнутый кот средствами SVG
Частичная стилизация через <tspan>
Если нужно применить стили или атрибуты только для определенной части, то можно использовать элемент <tspan> к разным частям текста в строке.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<text x="0" y="15">
<tspan>Жирный кот</tspan>,
<tspan>наклонный кот</tspan> и <tspan>подчеркнутый кот</tspan>.</text>
</svg>
Жирный кот, наклонный кот и подчеркнутый кот.
Цвет
Цвет текста задаётся через свойство fill.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 52">
<text y="50" font-size="40" font-weight="bold" font-family="Avenir, Helvetica, sans-serif" fill="red">Цветной кот</text>
</svg>
Цветной кот
Режим вывода текста
Японская письменность использует режим сверху вниз. Этот режим можно включить через атрибут writing-mode со значением tb (top-to-bottom). Я не знаю японских иероглифов, поэтому вставлю русские символы.
<svg xmlns="http://www.w3.org/2000/svg">
<text x="70" y="20">Неко - японский кот</text>
</svg>
Неко — японский кот
Добавление текста в заголовок страницы
Можно сделать красивый заголовок на странице, используя CSS:
header {
width: 80%;
margin: 0 auto;
}
svg text {
font-family: sans-serif;
text-transform: uppercase;
font-weight: 900;
font-size: 90px;
fill: blue;
}
<header>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 285 80">
<text x="0" y="66">Hawaii</text>
</svg>
</header>
Посмотреть демо.
SVG будет автоматически подстраиваться под размеры контейнера.
SVG может использовать любой шрифт, встроенный в страницу или из CSS. Текст доступен для поисковых роботов.
SVG-текст можно сделать ссылкой.
<header>
<img src="waves.svg" alt="Waves">
</header>
Но в этом случае вы не сможете использовать встроенный шрифт. Текст будет доступен для поисковых систем, но его нельзя скопировать.
Обводка текста
Обводка для текста делается похожим образом, как в CSS, только вместо указания цвета для текста нужно использовать свойство fill. Если цвет не указан, то используется чёрный цвет.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 80">
<text y="50" fill="#c96"
font-size="32px"
font-family="Futura Condensed ExtraBold, Arial Black, sans-serif"
stroke="yellow" stroke-width="2px">Обведи кота вокруг пальца</text>
</svg>
Обведи кота вокруг пальца
Присвоим атрибуту fill значение none, чтобы оставить только обводку.
Обведи кота вокруг пальца
При желании можно вынести код в стили.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 80">
<defs>
<style>
text {
fill: #c96; font-size:32px;
font-family: Futura Condensed ExtraBold, Arial Black, sans-serif;
stroke: yellow; stroke-width: 2px;
}
</style>
</defs>
<text y="50">Обведи кота вокруг пальца</text>
</svg>
Градиент
Текст можно сделать градиентным. Задаём цвета градиента при помощи linearGradient и присваиваем ему идентификатор. Связываем идентификатор с свойством fill.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient x1="0%" x2="0%" y1="0%" y2="100%">
<stop stop-color = "#ddd" offset = "0%"/>
<stop stop-color = "#FF00ee" offset = "100%"/>
</linearGradient>
</defs>
<text x="0" y="40" font-size="42" font-weight="bold" fill="url(#textgradient)" stroke="none">Градиентный кот</text>
</svg>
Градиентный кот
Текст вдоль кривой линии
Текст можно выводить не только строго вдоль вертикальной линии, но и вдоль замысловатой кривой.
Для начала нужно создать траекторию path в элементе defs. Элементу path добавляем атрибут id, чтобы связать текст в элементе textPath через xlink:href:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<path fill="none" stroke="#000000"
d="M0.057,0.024c0,0,10.99,51.603,102.248,51.603c91.259,0,136.172,53.992,136.172,53.992"/>
</defs>
<use xlink:href="#textpath"/>
<text x="10" y="100" font-size="24">
<textPath xlink:href="#textpath">
Кот вдоль кривой
</textPath>
</text>
</svg>
Кот вдоль кривой
Пример размещения текста вдоль окружности вынесен в отдельную статью.
Вернуться в раздел SVG
Реклама
Оформление содержимого в SVG с помощью CSS
Подробная статья об оформлении содержимого в элементе SVG <use>
и преодолении связанных с этим проблем.
Графика в формате SVG особо часто применяется для создания иконок и одной из самых распространенных техник для этого являются SVG-спрайты с использованием SVG use для инстанцирования иконок в нужном месте документа.
Инстанцирование иконок или любого другого содержимого SVG в элементе <use>
вызывает сложности при оформлении отдельных экземпляров. Цель этой статьи — дать вам обзор некоторых возможных способов обойти ограничения оформления, связанные с использованием <use>
.
Но перед тем как начать, давайте быстро рассмотрим основную структуру и группирование элементов в SVG, постепенно перейдя к <use>
, DOM, а затем вернемся обратно к CSS. Мы разберем, почему оформление <use>
может вызвать сложности и как их преодолеть.
Краткий обзор структуры SVG, группирования и ссылок на элементы в SVG
SVG включает в себя 4 основных элемента для определения, структурирования и создания ссылок на содержимое SVG в документе. Эти элементы дают возможность многократного использования изображений, оставляя код читаемым и поддерживаемым. Из-за природы SVG некоторые из этих элементов имеют функциональность, аналогичную соответствующим командам в графических редакторах.
4 основных группирующих и связывающих элемента SVG это <g>
, <defs>
, <use>
and <symbol>
.
Элемент <g>
(сокращение от “group”
) используется для логической группировки наборов связанных графических элементов. В терминах графических редакторов ( типа Adobe Illustrator) элемент <g>
по функционалу похож на функцию “Сгруппировать объекты”. Вы также можете думать о группе как о слое в графическом редакторе.
Группирование элементов полезно в тех случаях, когда вы хотите применить стиль ко всем элементам группы, а также, когда вы хотите анимировать все элементы группы, сохранив соотношение между ними.
Элемент <defs>
используется для задания многих вещей, в основном это задание паттернов типа градиентов, которые затем можно использовать для заливки других элементов SVG. Его можно использовать для задания любых элементов, которые вы собираетесь использовать где-либо на холсте.
Элемент <symbol>
комбинирует возможности <defs>
и <g>
в том, что используется для группирования элементов с заданием шаблона, на который можно ссылаться в других участках документа. В отличие от <defs>
, <symbol>
не используется для задания паттернов; как правило он используется для создания символов типа иконок, которые затем применяются во всем документе.
У элемента <symbol>
есть еще одно важное преимущество: он принимает атрибут viewBox
, который позволяет масштабирование внутри любой области видимости.
Элемент <use>
позволяет вам использовать в любом месте документа ранее определенный элемент. Он позволяет многократно использовать элементы, дает функциональность подобную копированию-вставке в графическом редакторе. С ним можно использоваться как отдельный элемент, так и группа, заданная в <g>
, <defs>
или <symbol>
.
Чтобы использовать элемент вам надо передать ссылку на этот элемент, идентификатор — это атрибут xlink:href
и спозиционировать его, задав атрибуты x
и y
. Вы можете применить стили к элементу <use>
и они будут каскадироваться на содержимое этого элемента.
Но что является содержимым <use>
? Куда он клонируется? И как каскад CSS работает с ним?
Перед тем как ответить на эти вопросы и с учетом того, что мы только по-быстрому разобрали структуру и группирование SVG, стоит упомянуть пару статей,которые позволят вам узнать больше об этих элементах, а также об атрибуте viewBox
в элементе <symbol>
:
SVG<use>
и теневой DOM
Когда вы ссылаетесь на элемент с помощью <use>
, ваш код выглядит примерно так:
<symbol viewBox="0 0 30 30">
<!-- icon content / shapes here -->
</symbol>
<use xlink:href="#my-icon" x="100" y="300" />
На экране отображается иконка, содержимое которой определено внутри <symbol>
, но на самом деле это содержимое элемента <use>
, которое является клоном <symbol>
.
Но элемент <use>
это всего лишь один самозакрывающийся элемент — в нем нет контента между открывающим и закрывающим тегами, так куда же клонируется содержимое <symbol>
?
Ответ — в теневой DOM (почему-то он всегда у меня ассоциируется с Бэтменом, не знаю почему).
Что такое теневой DOM?
Теневой DOM идентичен обычному DOM, за исключением того, что вместо того, чтобы быть частью дерева основного документа, узлы теневого DOM относятся к фрагменту документа, который является параллельным основному, но недоступным для его скриптов и стилей. Это дает авторам возможность создавать модульные компоненты, инкапсулируя скрипты и стили. Если вы когда-либо использовали элемент video
или диапазонный ввод в HTML5 и не поняли, откуда появлялись элементы управления видеоплеером или слайдер, то ответ тот же — теневой DOM.
В случае с элементом SVG <use>
, содержимое, на которое он ссылается, клонируется в фрагмент документа, “хостящийся” в <use>
. В данном случае <use>
это теневой хост.
Итак, содержимое <use>
(клон или копия элемента, на который он ссылается) присутствует внутри теневого фрагмента документа.
Другими словами, содержимое находится там, но оно невидимое. Такое же, как и содержимое обычного DOM, но не доступное высокоуровневым средствам, таким как селекторы CSS и JavaScript, скопированное в фрагмент документа, привязанный к <use>
.
Теперь, если вы дизайнер, вы можете подумать: “ОК, я понял, но есть ли способ проверить этот субдокумент и увидеть его содержимое”. Ответ — да, вы можете просматривать содержимое теневого DOM, используя инструменты разработки в Chrome (в Firefox на данный момент эта функция не доступна). Но для начала вам надо активировать инспектора теневого DOM во вкладке General на панели настроек. Это подробно описано здесь.
После того, как вы активировали инспекцию теневого DOM в инструментах разработчика, вы можете видеть клонированные элементы на панели элементов, также как и элементы обычного DOM. На следующем изображении показан пример элемента <use>
, ссылающегося на содержимое элемента <symbol>
. Обратите внимание, что “#shadow-root” и его содержимое являются клоном содержимого <symbol>
.
Используя инструменты разработчика Chrome, вы можете инспектировать содержимое элемента use внутри теневого DOM (“#shadow-root”, строка выделена серым цветом). На этом скриншоте инспектируется логотип Codrops из примера, который мы будем рассматривать в следующем разделе.
Глядя на инспектируемый код, вы можете увидеть, что теневой DOM очень похож на обычный, за исключением того, как он обрабатывается CSS и JavaScript основного документа. Существуют также иные различия между ними, которые мы не будем рассматривать в этой статье по причине их объема, поэтому если вы хотите узнать больше, я рекомендую вам следующие статьи:
С учетом моего ограниченного опыта взаимодействия с теневым DOM, я рассматриваю его как обычный DOM, который нужно по другому обрабатывать в части доступа CSS и JavaScript к его элементам. Это то, что важно для нас при работе с SVG: как воздействовать на содержимое <use>
внутри теневого DOM, ведь нам важно иметь возможность оформлять его. Весь смысл использования <use>
это возможность создавать различные копии элемента и в большинстве случаев нам надо иметь возможность стилизовать каждую копию по-разному. Например, это может быть лого в двух цветовых темах или многоцветные иконки для разных цветовых тем. Так что для нас важно иметь возможность сделать это с помощью CSS.
Как было сказано, содержимое теневого DOM недоступно для CSS в отличие от обычного DOM. Так как нам стилизовать его? Мы не можем использовать путь к потомкам типа такого:
use path#line {
stroke: #009966;
}
Потому как у нас нет доступа к теневому DOM с помощью обычных CSS селекторов.
Существует пара специальных селекторов, проникающих в теневой DOM и применяющих стили к узлам внутри него, но они не только плохо поддерживаются, но и их возможности ограничены в сравнении с длинным списком селекторов CSS для обычного DOM.
Кроме того, нам нужен простой способ оформить содержимое SVG <use>
без погружения в специфику теневого DOM, используя простой CSS и простой SVG.
Для того, чтобы добиться этого и получить больше контроля при оформлении содержимого <use>
, нам нужно взглянуть на это под другим углом, использовав возможности каскадирования и наследования в CSS.
Каскадирование стилей
Итак, CSS к SVG подключается тремя различными способами — внешними CSS стилями, внутренними стилями (внутри элемента <style>
) и строчными стилями (в атрибуте style
), вся разница в каскадировании.
В дополнение к свойствам CSS, элементы SVG можно оформлять используя презентационные атрибуты. Презентационные атрибуты это сокращения для задания CSS-свойств элементу. Думайте о них как о специальных стилевых свойствах. Их природа позволяет использовать их в стилевом каскаде, но в несколько непривычном виде.
В следующем фрагменте кода мы получаем простой розовый круг с желтой обводкой. stroke
, stroke-width
и fill
это презентационные атрибуты.
<svg viewBox="0 0 100 100">
<circle fill="deepPink" stroke="yellow" stroke-width="5" cx="50" cy="50" r="10"></circle>
</svg>
В SVG подмножество CSS-свойств может быть задано SVG-атрибутами и наоборот. Это значит, что не все CSS свойства могут быть заданы элементу SVG как презентационные атрибуты и не все презентационные атрибуты, доступные в SVG, могут быть определены в CSS.
Спецификация SVG перечисляет атрибуты SVG, которые могут задаваться как свойства CSS. Некоторые из этих атрибутов есть среди обычных правил CSS, например, opacity
и transform
, а некоторые применяются только к SVG — fill
, stroke
и stroke-width
.
В SVG2 этот список также включает x
, y
, width
, height
, cx
, cy
и несколько иных презентационных атрибутов, которые нельзя задать по спецификации SVG 1.1. Новый список можно найти в спецификации SVG2.
Возможно, вы, как и я ожидаете, что презентационные атрибуты имеют самую высокую специфичность среди всех стилевых правил. Ведь обычно внешние стили переписываются внутренними декларациями, а те в свою очередь переписываются строчными стилями атрибутов — они имеют максимальную специфичность, а, соответственно, и приоритет перед остальными стилями. И хотя это ожидание имеет смысл, действительный механизм работы отличен.
На самом деле, презентационные атрибуты рассматриваются как низкоуровневые “авторские таблицы стилей” и они переписываются остальными стилевыми декларациями: внешними, внутренними и инлайновыми стилями. Их единственная сила это приоритет перед унаследованными стилями. И все.
Теперь, когда мы выяснили это, вернемся к нашему элементу <use>
и его содержимому.
Мы знаем, что мы не можем задать стили внутри <use>
, используя CSS селекторы.
Но мы также знаем, что как и в случае с элементом <g>
, стили примененные к <use>
будут унаследованы всеми его потомками (которые находятся в теневом DOM).
Итак, сначала попытаемся изменить цвет заливки (fill
) элемента внутри <use>
, применив селектор к самому элементу <use>
с расчетом, что каскад и наследование сделают свое дело.
Однако, это вызывает пару вопросов:
- Цвет заливки будет унаследован всеми потомками элемента
<use>
, даже теми, к которым вы не хотите применять стили (но если внутри<use>
у вас всего один элемент, то этой проблемы не будет). - Если вы экспортировали SVG из графического редактора или по каким-либо иным причинам не можете изменять код SVG, тогда вы в конечном итоге будете работать с SVG, к которому уже применены презентационные атрибуты (если вы явно не отмените это при экспорте в формат SVG) и значения этих атрибутов будут иметь приоритет над унаследованными от
<use>
.
И даже если вы можете редактировать код SVG и можете избавиться от них, я настоятельно рекомендую этого не делать по следующим причинам:
- Удаление атрибутов ради последующей установки определенных свойств сбросит значения этих свойств на дефолтные, а это, как правило, черная заливка и обводка (применительно к цветам).
- Сбрасывая значения, вы вынуждаете себя задавать стили для всего набора свойств.
- Презентационные атрибуты, которые изначально заданы, являются отличным запасным вариантом на случай возникновения проблем с внешними стилями. Если CSS не загрузится, у ваших иконок будет по-прежнему привлекательный вид.
Итак, у нас есть эти атрибуты, но при этом мы хотим оформить различные экземпляры иконок по разному.
Это делается за счет вынуждения презентационных атрибутов к унаследованию стилей, заданных <use>
или нахождения способа обойти переопределения этих значений. Чтобы сделать это, нам придется использовать всю мощь каскадирования CSS.
Давайте начнем с простых примеров и постепенно перейдем к сложным.
Переписывание значений презентационных атрибутов с помощью CSS
Презентационные атрибуты переписываются любой декларацией стилей. Мы можем это использовать, для того, чтобы презентационный атрибут получил значение, унаследованное от стилей <use>
.
Это просто благодаря ключевому слову CSS inherits. Взгляните на следующий пример — иконка мороженого, нарисованная одним контуром, цвет которого мы хотим изменять в разных экземплярах. Иконка создана Эрин Агноли из Noun Project.
<svg>
<symbol>
<path fill="#000" d="M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844 c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442 c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933 c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04 c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929 C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907 c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48 c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631 c0,1.684-0.914,3.148-2.266,3.958h35.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z M50.01,86.723L27.73,49.13h54.541L50.01,86.723z"/>
</symbol>
</svg>
Содержимое нашей иконки с мороженым (path
) определено внутри элемента <symbol>
, а, значит, оно по умолчанию не будет выводится на холст.
Мы выводим множественные экземпляры иконки с помощью <use>
.
<svg viewBox="0 0 100 125">
<use xlink:href="#ic" x="0" y="0" />
</svg>
<svg viewBox="0 0 100 125">
<use xlink:href="#ic" x="0" y="0" />
</svg>
Ширину и высоту иконок мы задаем с помощью CSS. Я использую те же размеры, что и у viewBox
, но они не должны быть идентичными. Однако, чтобы избежать избытка пустого пространства внутри SVG, убедитесь, что вы сохраняете соотношение между сторонами.
.icon {
width: 100px;
height: 125px;
}
С этим кодом мы получили следующий результат:
Заметьте, что благодаря добавленным черным рамкам вокруг наших SVG вы видите границы каждого из них, в том числе и первого, в котором содержимое не рендерится. Запомните: SVG-документ, в котором вы определили symbol
будет выводится на страницу, но без содержимого. Чтобы предотвратить это, используйте свойство display: none
на первом SVG. Если вы не спрячете SVG с определениями иконок, он будет выводится на экран даже если вы не зададите для него размеры — он займет дефолтные 300 на 150 пикселей (это значение по умолчанию для незамещаемых элементов в CSS) и вы получите ненужный вам пустой блок на экране.
Теперь попробуем изменить цвет заливки для каждого экземпляра иконки:
use.ic-1 {
fill: skyblue;
}
use.ic-2 {
fill: #FDC646;
}
Цвет заливки иконок по-прежнему не меняется, так как унаследованный цвет переписывается атрибутом fill="#000"
в элементе path
. Чтобы это не произошло, нам надо вынудить path
унаследовать цвет:
svg path {
fill: inherit;
}
Вуаля! Цвета, заданные элементам <use>
теперь применяются к path
каждого из них. Проверьте демо и поэкспериментируйте со значениями, создавая экземпляры и задавая им разные цвета:
See the Pen mErELQ by prgssr (@prgssr) on CodePen.
Теперь эта техника работает, после того как мы вынудили содержимое <use>
унаследовать стили. Но во многих случаях это не совсем то, что вам нужно. Есть и другие способы оформления, к некоторым из них мы сейчас перейдем.
Оформление содержимого <use>
с помощью свойства CSS all
Некоторое время назад, при работе над иконкой, активируемой с помощью <use>
, мне надо было, чтобы один из элементов внутри него унаследовал все стили <use>
, такие как fill
, stroke
, stroke-width
, opacity
и даже transform
. Таким образом, мне надо было контролировать все эти атрибуты через CSS, сохраняя при этом в разметке все презентационные атрибуты в качестве запасного варианта.
Если вы столкнетесь с похожей задачей, вы, вероятно, решите, что она займет слишком много времени, если все делать в CSS:
path#myPath {
fill: inherit;
stroke: inherit;
stroke-width: inherit;
transform: inherit;
/* ... */
}
Рассмотрев этот сниппет, вы заметите паттерн, а, значит, имело бы смысл объединить все указанные свойства в одно и задать ему значение inherit
.
К счастью, нам поможет свойство CSS all
. В моем справочнике по CSS упоминается использование свойства all
для оформления SVG, но стоит освежить наши знания.
Используя свойство all
мы можем сделать так:
path#myPath {
all: inherit;
}
Это прекрасно работает во всех браузерах, поддерживающих all
, однако надо учитывать следующий важный момент: эта декларация задает элементу наследование буквально всех свойств его родителя, в том числе и тех, которые вы не хотите задавать элементу. Поэтому, если вы не хотите, чтобы стилизовались все свойства CSS, вам это не подойдет — это крайняя мера и она частично подходит только тогда, когда у вас есть нестилизованный элемент и полный контроль над его свойствами в CSS. Если вы используете эту декларацию и не определяете значения для всех свойств CSS, они будут каскадироваться пока не найдут значение для наследования, в большинстве случаев это дефолтные стили браузера.
Заметьте, что это относится только к атрибутам, которые можно устанавливать с помощью CSS, а не к атрибутам, задаваемым только в SVG. Если атрибут может быть задан с помощью CSS — он унаследует стили, иначе нет.
Возможность активировать наследование презентационными атрибутами всех стилей <use>
, но что если у вас иконка, состоящая из нескольких элементов и вы не хотите, чтобы все они унаследовали один и тот же цвет заливки? Что если вы хотите применять множество различных цветов заливки для разных потомков? Задание одного стиля в <use>
уже не подходит. Нам нужно что-то другое, чтобы каскадировать нужные цвета к нужным элементам.
Использование переменной CSS currentColor
для оформления содержимого <use>
Использование переменной CSS currentColor в сочетании с техникой, описанной выше, позволяет определить два цвета для элемента, а не один. Год назад Фабрис Вайнберг написал об этом статью в своем блоге на Codepen.
Идея состоит в том, чтобы одновременно применять к <use>
свойства fill
и color
, а затем каскадировать эти свойства к содержимому <use>
, используя возможности переменной currentColor
. Посмотрим на пример кода, чтобы понять, как это работает.
Предположим, мы хотим оформить это минималистичное лого Codrops, используя 2 цвета — один для передней капли, а второй для задней.
Во-первых, начнем с кода для этого изображения: у нас есть symbol
, содержащий описание иконки и три экземпляра <use>
, создающие три экземпляра лого.
<svg>
<symbol viewBox="0 0 23 30">
<path fill="#aaa" d="M22.63,18.261c-0.398-3.044-2.608-6.61-4.072-9.359c-1.74-3.271-3.492-5.994-5.089-8.62l0,0 c-1.599,2.623-3.75,6.117-5.487,9.385c0.391,0.718,0.495,1.011,0.889,1.816c0.143,0.294,0.535,1.111,0.696,1.43 c0.062-0.114,0.582-1.052,0.643-1.162c0.278-0.506,0.54-0.981,0.791-1.451c0.823-1.547,1.649-2.971,2.469-4.33 c0.817,1.359,1.646,2.783,2.468,4.33c0.249,0.47,0.513,0.946,0.791,1.453c1.203,2.187,2.698,4.906,2.96,6.895 c0.292,2.237-0.259,4.312-1.556,5.839c-1.171,1.376-2.824,2.179-4.663,2.263c-1.841-0.084-3.493-0.887-4.665-2.263 c-0.16-0.192-0.311-0.391-0.448-0.599c-0.543,0.221-1.127,0.346-1.735,0.365c-0.56-0.019-1.095-0.127-1.599-0.313 c1.448,3.406,4.667,5.66,8.447,5.78C19.086,29.537,23.469,24.645,22.63,18.261z"/>
<path fill="#ddd" d="M6.177,11.659c0.212,0.367,0.424,0.747,0.635,1.136c0.164,0.303,0.333,0.606,0.512,0.927 c0.683,1.225,1.618,2.898,1.755,3.937c0.144,1.073-0.111,2.056-0.716,2.769c-0.543,0.641-1.315,1.014-2.186,1.067 c-0.87-0.054-1.643-0.43-2.186-1.067c-0.604-0.713-0.858-1.695-0.715-2.771c0.137-1.036,1.072-2.712,1.755-3.936 c0.18-0.32,0.349-0.623,0.513-0.927C5.752,12.404,5.964,12.026,6.177,11.659 M6.177,5.966L6.177,5.966 c-1.02,1.649-2.138,3.363-3.247,5.419c-0.932,1.728-2.344,3.967-2.598,5.88c-0.535,4.014,2.261,7.09,5.846,7.203 c3.583-0.113,6.379-3.189,5.845-7.203c-0.255-1.912-1.666-4.152-2.598-5.88C8.314,9.329,7.196,7.617,6.177,5.966L6.177,5.966z"/>
</symbol>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
<svg>
<use xlink:href="#codrops"/>
</svg>
Если мы зададим цвет заливки (fill
) в элементе <use>
для каждого экземпляра, этот цвет будет унаследован обоими каплями, что не является нашей целью.
Поэтому вместо определения цвета заливки и каскадирования его обычным способом, мы будем использовать переменную currentColor
, чтобы меньшая капля на переднем плане была другого цвета и это значение мы зададим с помощью свойства color
.
Для начала нам надо вставить currentColor
туда, где мы хотим применить этот цвет — это будет место в разметке, где определяется иконка, то есть внутри <symbol>
. Теперь этот фрагмент выглядит так:
<svg>
<symbol viewBox="0 0 23 30">
<path fill="#aaa" d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
Затем нам надо удалить презентационный атрибут fill
из второй капли и позволить ей унаследовать цвет заливки (fill
) от элемента <use>
с помощью inherit
.
Если бы мы использовали ключевое слово inherit
, чтобы вынудить презентационные атрибуты унаследовать значения от <use>
, обе части унаследовали бы одинаковое значение, а currentColor
не имела бы никакого эффекта. Поэтому в этой технике нам надо удалить тот атрибут, который мы хотим задать через CSS, а оставить только тот, в котором мы будем использовать currentColor
.
<svg>
<symbol viewBox="0 0 23 30">
<path d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
Теперь, используя свойства fill
и color
в <use>
мы добавим стили к капле из логотипа:
.codrops-1 {
fill: #4BC0A5;
color: #A4DFD1;
}
.codrops-2 {
fill: #0099CC;
color: #7FCBE5;
}
.codrops-3 {
fill: #5F5EC0;
color: #AEAFDD;
}
Каждый элемент <use>
получает собственное значение fill
и color
. В каждом из них цвет fill
каскадируется и заполняет первый контур, не имеющий атрибута fill
, а цвет свойства color
используется для задания атрибута fill
во втором контуре.
Так что произошло следующее: значение текущего цвета просочилось в стили содержимого элемента <use>
за счет использования переменной currentColor
. Изящно, не правда, ли?
Вот демо с использованным кодом:
See the Pen aZmZXV by prgssr (@prgssr) on CodePen.
Этот двухцветная техника отлично подходит для двухцветных лого. В своей статье Фабрис создал три различных версии лого Sass, изменяя цвет текста относительно фона.
Ключевое слово currentColor
это единственная доступная переменная CSS на данный момент. Однако, если бы у нас было бы больше переменных, могли бы мы их использовать для заполнения еще большего количества значений в содержимом <use>
? Да, могли бы. Амелия Беллами-Ройдс год назад представила концепцию этого в своем блоге на Codepen. Посмотрим, как это работает.
Будущее: оформление содержимого <use>
c помощью переменных CSS
Используя кастомные свойства CSS (переменные CSS) вы можете оформить содержимое <use>
, не вынуждая браузер переписывать значения презентационных атрибутов.
Как сказано на MDN, CSS переменные это сущности, заданные авторами или пользователями веб-страниц для хранения и использования определенных значений по всему документу. Они задаются с использованием кастомных свойств и доступны с использованием специфичной нотации var()
. Они очень похожи на переменные из CSS-препроцессоров, но более гибкие и могут делать то, на что неспособны переменные препроцессоров. (Скоро в справочнике CSS появится статья о них).
Переменные CSS, как и переменные препроцессоров могут найти множество использований, но цветовая темизация это один из самых распространенных вариантов. И в этом разделе мы рассмотрим, как мы можем их применить при оформлении SVG.
Мы начнем с изображения, заданного в symbol
и инстанцированного с помощью <use>
, применив технику только к изображению; концепция примененная к стилю содержимого <use>
может применяться к любому количеству элементов <use>
на ваше усмотрение.
Мы будем использовать изображение этого прикольного робота-хипстера, созданного Freepik.
Код робота содержит все составляющие его цвета:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
Теперь, мы не будем использовать переменные CSS в качестве значений атрибута fill
для каждого контура. Вместо этого мы будем их использовать в качестве цветов заливки используя свойство CSS fill
, сохранив на месте все атрибуты fill
. Эти атрибуты будут использоваться в качестве запасного варианта для браузеров, не поддерживающих переменные CSS — изображение будет выглядеть в своем изначальном виде, если переменные CSS не работают.
С добавленными переменными код будет следующим:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
Так как инлайновые теги style
переписывают презентационные атрибуты, браузеры с поддержкой CSS-переменных будут использовать эти переменные для задания цвета заливки (fill
). А браузеры, не поддерживающие их, будут использовать атрибут fill
.
Затем нам надо задать значения для переменных в CSS. Но сначала инстанцируем изображение с помощью <use>
:
<svg>
<<use> xlink:href="#robot" />
</svg>
После этого зададим значения переменных для use
, чтобы они могли каскадироваться к его содержимому. Выбранные вами цвета создадут цветовую схему рисунка. Так как в нашем роботе используется три основных цвета, мы назовем их primary
, secondary
и tertiary
.
#robot-1 {
--primary-color: #0099CC;
--secondary-color: #FFDF34;
--tertiary-color: #333;
}
Вы по-прежнему можете использовать свойства fill
и color
вместе с этими переменными, но вы можете вполне обойтись и без этого. Итак, с цветами заданными в наших переменных, робот выглядит так:
Вы можете использовать сколько угодно копий изображения и для каждой из них задать набор различных цветов, создав различные темы. Это частично полезно, когда вы хотите оформить лого различными способами в зависимости от контекста и в других подобных случаях.
Как было упомянуто, браузеры, не поддерживающие CSS-переменные используют заданные презентационные атрибуты в качестве запасного варианта, а браузеры с поддержкой переменных CSS используют их для заполнения свойства fill
и переписывания атрибутов. Но что происходит, если браузер поддерживает переменные CSS, но вы забыли задать эти переменные в стилях или задали некорректное значение?
Для нашего робота-хипстера мы задали три переменных и только несколько его фрагментов не зависят от них — ведь он изначально разрабатывался для возможной темизации. Поэтому если вы запустите этот код в браузере с поддержкой переменных CSS и удалите все декларации с объявлением этих переменных, вы получите следующий результат:
Если значения переменных не заданы или не корректны, браузер будет использовать свой цвет по умолчанию, а это обычно черный цвет для заливки и обводки в SVG.
Обойти это можно, задав другой цвет в качестве запасного варианта для поддерживающих браузеров. Синтаксис переменных CSS позволяет сделать так: вместо передачи функции var()
имени переменной в качестве аргумента, вы передаете два аргумента, разделенных запятой — имя переменной и запасной вариант, в данном случае это будет значение для презентационного атрибута.
Итак, теперь код нашего робота выглядит так:
<svg>
<symbol viewBox="0 0 340 536">
<path d="..." fill="#fff" />
<path d="..." fill="#D1312C" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#1E8F90" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#fff" />
<path d="..." fill="#6A4933" />
<path d="..." fill="#F2B42B" />
<path d="..." fill="#fff" />
<!-- rest of the shapes -->
</symbol>
</svg>
И это все. Если у какой-либо переменной не будет задано значение, у браузера всегда будет в запасе цвет, заданный в качестве запасного варианта. Замечательно.
Используя эту технику, вы можете выводить этого робота где угодно на странице с помощью <use>
, задавая для каждого экземпляра разные цвета и получая различные цветовые темы в итоге.
Вы можете поэкспериментировать с демо, создать сколько угодно копий робота и раскрасить его любыми цветами — не забудьте только, что для этого обязательно надо использовать браузер с поддержкой переменных CSS:
See the Pen vKXXYP by prgssr (@prgssr) on CodePen.
Если вы просматриваете это демо в браузере с поддержкой переменных CSS, то среди прочих вы увидите голубую с желтым версию робота, как мы и задавали в CSS-переменных. Иначе вы увидите трех одинаковых роботов с цветом запасного варианта.
Подводя итоги
Это была большая статья.
Используя возможности каскада CSS, оформление содержимого <use>
, хранимого в теневом DOM, становится менее сложным. А с переменными CSS (currentColor
или с пользовательскими свойствами) мы можем проникнуть в теневой DOM и кастомизировать нашу графику, как хотим, создавая при этом запасной вариант на случай проблем.
Лично мне очень симпатично сочетание переменных CSS и SVG. Мне нравятся их совместный функционал, особенно в части создания механизма запасного варианта.
Мы также можем получить другие способы оформления содержимого<use>
в будущем, так как продолжаются дискуссии об использовании переменных CSS в качестве параметров SVG — поэтому данная статья не покрывает все, что можно узнать по этой теме.
Работа с многократно используемым содержимым SVG является одним из сложных вопросов SVG, это связано с поведением и местом расположения клонируемого кода. Здесь возникает очень много смежных вопросов, которые могут стать темой отдельных статей.
javascript: Как изменить цвет SVG?
Решение SVG
Изображение в формате base64 нельзя стилизовать обычными способами:
Но с помощью фильтров SVG вы можете раскрасить изображение в любой цвет
На мой взгляд, есть очень полезная статья об использовании фильтров для раскрашивания изображений.
Фильтр для покраски в черный цвет линий:
<!-- black filter -->
<filter x="-20" y="-20">
<feColorMatrix in="SourceGraphic" type="matrix"
values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0
"/>
</filter>
в приведенных ниже примерах path
отвечает за окраску фона
<path d="M 0 0L 58 0L 58 57L 0 57L 0 0Z" fill="white"/>
К сожалению из вопроса я так и не понял, что вы хотите покрасить в черный цвет: фон или контур изображения, поэтому я приведу два варианта.
# 1 белый фон, черные линии
<svg viewBox="0 0 58 57" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
<!-- black filter -->
<filter x="-20" y="-20">
<feColorMatrix in="SourceGraphic" type="matrix"
values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0
"/>
</filter>
</defs>
<path d="M 0 0L 58 0L 58 57L 0 57L 0 0Z" fill="white"/>
<image filter="url(#BlackFilter)" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA5CAYAAABnLziGAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo2NEU2MTVDOEVCQzJFNzExOEZEREJDOEMwMDc0QjFGOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0NkI1NEZDMEVBRUUxMUU3OUNDQURGQjhFQzQwNTExNSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0NkI1NEZCRkVBRUUxMUU3OUNDQURGQjhFQzQwNTExNSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjgzNjI4N0NBMDFERkU3MTFBNjFFQzgyMkEyM0JDMTdBIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY0RTYxNUM4RUJDMkU3MTE4RkREQkM4QzAwNzRCMUY4Ii8+IDwvcmRmOkRl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" />
</svg>
# 2 черный фон, белые линии
<svg viewBox="0 0 58 57" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
<!-- white filter -->
<filter x="-20" y="-20">
<feColorMatrix in="SourceGraphic" type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
"/>
</filter>
</defs>
<path d="M 0 0L 58 0L 58 57L 0 57L 0 0Z" fill="black"/>
<image preserveAspectRatio="none" filter="url(#WhiteFilter)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA5CAYAAABnLziGAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo2NEU2MTVDOEVCQzJFNzExOEZEREJDOEMwMDc0QjFGOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0NkI1NEZDMEVBRUUxMUU3OUNDQURGQjhFQzQwNTExNSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0NkI1NEZCRkVBRUUxMUU3OUNDQURGQjhFQzQwNTExNSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjgzNjI4N0NBMDFERkU3MTFBNjFFQzgyMkEyM0JDMTdBIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY0RTYxNUM4RUJDMkU3MTE4RkREQkM4QzAwNzRCMUY4Ii8+IDwvcmRmOkRl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" />
</svg>
Автор: Alexandr_TT
Размещён: 17.01.2018 09:50
Минутку …
Включите файлы cookie и перезагрузите страницу.
Этот процесс автоматический. Ваш браузер в ближайшее время перенаправит вас на запрошенный контент.
Подождите до 5 секунд…
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) — []) + (! + [] — (!! [])) + (! + [] + (!! []) +! ! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [])) / + ( (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + [] ) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [ ]))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [])) / + ((! + [] + (!! []) +! ! [] + !! [] + []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [ ] + []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [ ]) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [ ] + (!! []) + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [])) / + ((! + [] + (!! []) — [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! []) ) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] ) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + []) + (! + [] + (! ! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! [] ) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] ) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) )
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + [] ) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] +! ! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [ ]) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + ( !! []) + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] +! ! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [ ] — (!! [])) + (! + [] — (!! [])) + (! + [] + (!! []) + !! []) + (! + [] + ( !! []) + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) +! ! [] + !! [] + !! [] + !! [] + !! [])) / + ((! + [] + (!! []) — [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) — []) + (! + [] — (! ! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (+ !! []) + (! + [ ] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] ) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + ( !! []) + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + []) + (! + [] + (! ! []) — []) + (+ !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])))
+ ((! + [] + (!! []) + !! [] + !! [ ] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] +! ! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] — (!! [])) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! []) + ( ! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + ( !! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + ( ! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) )
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + [] ) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + ( ! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (! ! [])
Минутку…
Включите файлы cookie и перезагрузите страницу.
Этот процесс автоматический. Ваш браузер в ближайшее время перенаправит вас на запрошенный контент.
Подождите до 5 секунд…
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [ ] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! [])) / + ((+ !! [] + []) + (! + [] + (!! []) + !! [] + !! [ ] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [])) / + ((! + [] + (!! []) — [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [ ] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] ) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] +! ! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! [] ) + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] +! ! []) + (+ !! [])) / + ((! + [] + (!! []) + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! []) + (+ !! []) + (! + [] + ( !! []) — []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (+! ! []) + (! + [] + (!! []) + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [ ] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + [ ]) + (! + [] + (!! []) — []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [ ] + !! []) + (+ !! []) + (! + [] + (!! [ ]) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! [] ) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + []) + (! + [] — (!! [])) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] +! ! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + ( ! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [ ] + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [ ] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! [ ]))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! [ ])) / + ((! + [] + (!! []) — [] + []) + (! + [] + (!! []) + !! [] + !! [] +! ! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) — []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [ ] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []))
+ ( (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] +! ! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! [ ]) + !! [] + !! []) + (+ !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) — []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] +! ! [] + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [ ] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] ))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! []) + (+ !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! [ ]) + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (+ !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] +! ! []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (+ !! []) + (! + [] + (! ! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] +! ! [] + !! [] + !! []) + (+ !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []))
+ ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] +! ! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! []) + (! + [ ] — (!! [])) + (! + [] — (!! [])) + (! + [] + (!! []) + !! []) + (! + [] + ( !! []) + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] + (!! []) +! ! [] + !! [] + !! [] + !! [] + !! [])) / + ((! + [] + (!! []) + !! [] + !! [] + !! [] + !! [] + !! [] + !! [] + []) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []) + (! + [] + (!! []) + !! []) + (! + [] — (!! [])) + (! + [] + (!! []) + !! [] + !! [] + !! []) + (! + [] + (!! [ ]) + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) +! ! [] + !! [] + !! [] + !! [] + !! []) + (! + [] + (!! []) + !! [] + !! []))
Изменить цвет SVG — HTML и CSS — Форумы SitePoint
csosa:
хм, похоже, это не работает,
Я не вижу этого класса
Наверное, стоило взять несколько больше
раз, и присмотреться повнимательнее.
- Открыть этот файл…
http://54.172.86.136/wp-content/uploads/2019/05/User.svg
… в текстовом редакторе, и вы увидите это…
Xml version = "1.0" encoding = "utf-8"?>
- В строках 5, 6 и 7 вы найдете это…
<svg>
<symbol viewBox="0 0 23 30">
<path fill="#aaa" d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
- Заменить на…
<svg>
<symbol viewBox="0 0 23 30">
<path d="..."/>
<path fill="currentColor" d="..."/>
</symbol>
</svg>
- Нажмите «Файл»
- Нажмите «Сохранить»
- Выпейте.
- Работа выполнена.
Если сложно, то скачайте и откройте вложение…
Пользователь.zip (684 байта)
… который содержит измененный файл « User.svg ».
Замените существующий файл этим.
зубчатый
Цвет изображения SVG с CSS
Привет,
Я рад, что вам понравился мой плагин 🙂
Не могли бы вы дать ссылку на сайт?
Это довольно просто, вам просто нужно настроить таргетинг на правильный класс вашего элемента и применить цвет или цвет заливки.
Например:
.your-svg-class {fill: red; красный цвет; }
Скорее всего, вам нужно будет использовать только один из них (заливку или цвет), обычно заливку, но это зависит конкретно от вашего SVG.
Надеюсь, это поможет. Дай мне знать, как дела.
PS. Я работаю над веб-сайтом, где есть несколько советов и руководств. Пока нет ETA, но он находится в процессе разработки.
Привет,
Сайт по-прежнему локальный, но я использую плагин для вставки только иконок.
Я уже пытался сделать, как вы говорите, но это не сработало.
Должен ли я сохранять файл svg определенным образом?
Спасибо
Привет,
Трудно сказать, что происходит. У вас должно получиться нормально экономить.
Не могли бы вы отправить файл SVG, чтобы я мог протестировать его?
Привет,
Я попробовал и попробовал еще раз.
Внутри WPbakery и внутри обычной статьи WP ничего не окрашено.
Прилагаю тестовый svg.
https://www.dropbox.com/s/ugo0u01k0jyw7e0/SVGtest.svg?dl=0
Спасибо
Вам необходимо убедиться, что SVG отображается встроенным, иначе CSS не коснется элементов в нем. Вы можете проверить, отображается ли он как код SVG или как тег IMG с SVG в качестве src.
CSS для воздействия на 2 элемента в предоставленном SVG будет:
круг # Ellipse_97 {
заливка: зеленый;
}
path # Path_461 {
заливка: синий;
}
Вы можете изменить цвета по своему усмотрению.
Если вы хотите изменить цели, откройте свой SVG в редакторе кода, например, в возвышенном тексте. Вы можете добавить свои собственные классы к 2 элементам и вместо этого нацелить их.
Привет,
извините, я не могу заставить его работать …
Даже с кодом, который вы предоставили.
Есть определенно что-то, что ускользает от меня.
Мне понятно, как менять объекты внутри SVG-файла, это не проблема.
Но я не могу понять, почему он не меняет цвета с помощью css.
Надо что-то активировать в настройках?
Спасибо
Привет,
Вам потребуется активировать расширенный режим, и вам нужно будет убедиться, что ваш SVG отображается встроенным, чтобы иметь возможность нацеливаться на внутренние элементы.
У меня тоже такая проблема. У меня активирован расширенный режим, svg отображается встроенным, но не может нацеливаться на внутренние элементы с помощью css.
- Этот ответ был изменен 9 месяцев назад пользователем Grafiker29.
Привет @ grafiker29
Вам действительно стоит начать свой собственный поток, даже если он кажется похожим.
Если ваш SVG является встроенным и вы можете видеть внутренние элементы в инспекторе, вам просто нужно разработать CSS, который нужно использовать для управления этими элементами.
ЕСЛИ ваш SVG является встроенным, это конец строки для моего плагина, остальное полностью внешнее.
Обычно, если вы не можете что-то изменить с помощью CSS, вам нужно повысить конкретность.
Например, если это не работает:
.your-svg-class {fill: red; }
Может показаться, что есть CSS более высокого уровня, который уже сообщает ему, какой цвет должен быть … ИЛИ у вас уже есть цвета, установленные в вашем коде SVG.
Вам просто нужно уточнить, насколько это возможно. Наиболее крайняя версия этого будет:
html body .your-svg-class {fill: red;}
Это может даже не сработать, это должно соответствовать вашему точному коду. Но я надеюсь, что это поможет.
Для ясности, это после того, как мой плагин выполнил свою работу. Возможно, вам придется попросить разработчика разобраться с CSS за вас.
В этом году я собираюсь создать сайт, полный ресурсов, чтобы помочь людям по-настоящему использовать возможности моего плагина. Я расскажу, как написать CSS для управления вашими элементами SVG.
А пока, если вы хотите, чтобы я посмотрел, пожалуйста, откройте новую тему и поделитесь своим URL-адресом и информацией о проблеме, и я с радостью посмотрю.
цветов — Веб-технологии для разработчиков
Атрибут color
используется для предоставления потенциального косвенного значения, currentcolor
, для атрибутов fill
, stroke
, stop-color
, flood-color
и lighting-color
.
Примечание. В качестве атрибута представления цвет
может использоваться как свойство CSS. См. Цвет CSS для получения дополнительной информации.
В качестве атрибута представления он может применяться к любому элементу, но, как отмечалось выше, он не оказывает прямого влияния на элементы SVG.
Замечания по использованию
Значение | <цвет> | наследство |
---|---|
Значение по умолчанию | Зависит от пользовательского агента |
Анимационный | Есть |
Пример
html, body, svg { высота: 100%; }
Технические характеристики
Совместимость с браузером
Обновите данные о совместимости на GitHub
Рабочий стол | Мобильный | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android |
Opera для Android | Safari на iOS | Samsung Internet | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
цвет | Chrome ? | Кромка ? | Firefox ? | IE ? | Opera ? | Safari ? | WebView Android ? | Chrome Android ? | Firefox Android ? | Опера Android ? | Safari iOS ? | Samsung Internet Android ? |
Условные обозначения
-
Совместимость неизвестна - Совместимость неизвестна
Давайте сделаем разноцветные значки с символами SVG и переменными CSS
, Сара Даян,
, Creative Things, Кайл Адамс,
Давно прошли времена использования изображений и CSS-спрайтов для создания иконок для Интернета.С появлением веб-шрифтов, иконочные шрифты стали решением номер один для отображения значков в ваших веб-проектах.
Шрифты — векторные, поэтому вам не нужно беспокоиться о разрешении. Они используют те же свойства CSS, что и текст. В результате у вас есть полный контроль над размером, цветом и стилем. Вы можете добавлять преобразования, эффекты и украшения, такие как вращения, подчеркивания или тени.
Неудивительно, что такие проекты, как Font Awesome, по сей день были загружены более 15 миллионов раз только на npm.
Иконочные шрифты не идеальны, хотя , поэтому все большее число людей предпочитают использовать встроенные изображения SVG. CSS Tricks составил список областей, в которых шрифты значков уступают нативным элементам SVG: резкость, позиционирование или даже сбои из-за междоменной загрузки, специфичных для браузера ошибок и блокировки рекламы. Теперь вы можете обойти большинство из этих проблем, сделав шрифты значков безопасным выбором.
Однако есть одна вещь, которая остается абсолютно невозможной с иконочными шрифтами: поддерживает многоцветность .Только SVG может это сделать.
TL; DR : в этом посте подробно рассказывается, как и почему. Если вы хотите понять весь мыслительный процесс, читайте дальше.
2024 © Все права защищены.
Добавить комментарий