DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
SVG is a great format for icons. Vector formats look crisp and razor sharp, no matter the size or device — and we get tons of design control when using them inline.
SVG also gives us another powerful feature: the ability to manipulate their properties with CSS. As a result, we can make quick and simple interactions where it used to take crafty CSS tricks or swapping out entire image files.
Those interactions include changing color on hover states. It sounds like such a straightforward thing here in 2019, but there are actually a few totally valid ways to go about it — which only demonstrates the awesome powers of SVG more.
First off, let’s begin with a little abbreviated SVG markup:
<svg class="icon">
<path .../>
</svg>
Target the .icon
class in CSS and set the SVG fill
property on the hover state to swap colors.
.icon:hover {
fill: #DA4567;
}
This is by far the easiest way to apply a colored hover state to an SVG. Three lines of code!
SVGs can also be referenced using an <img>
tag or as a background image. This allows the images to be cached and we can avoid bloating your HTML with chunks of SVG code. But the downside is a big one: we no longer have the ability to manipulate those properties using CSS. Whenever I come across non-inline icons, my first port of call is to inline them, but sometimes that’s not an option.
I was recently working on a project where the social icons were a component in a pattern library that everyone was happy with. In this case, the icons were being referenced from an <img>
element. I was tasked with applying colored :focus
and :hover
styles, without adjusting the markup.
So, how do you go about adding a colored hover effect to an icon if it’s not an inline SVG?
CSS Filters
CSS filters allow us to apply a whole bunch of cool, Photoshop-esque effects right in the browser. Filters are applied to the element after the browser renders layout and initial paint, which means they fall back gracefully. They apply to the whole element, including children. Think of a filter as a lens laid over the top of the element it’s applied to.
These are the CSS filters available to us:
brightness(<number-percentage>);
contrast(<number-percentage>);
grayscale(<number-percentage>);
invert(<number-percentage>);
opacity(<number-percentage>);
saturate(<number-percentage>);
sepia(<number-percentage>);
hue-rotate(<angle>);
blur(<length>);
drop-shadow(<length><color>);
All filters take a value which can be changed to adjust the effect. In most cases, this value can be expressed in either a decimal or percent units (e.g. brightness(0.5)
or brightness(50%)
).
Straight out of the box, there’s no CSS filter that allows us to add our own specific color.
We have hue-rotate()
, but that only adjusts an existing color; it doesn’t add a color, which is no good since we’re starting with a monochromatic icon.
The game-changing bit about CSS filters is that we don’t have to use them in isolation. Multiple filters can be applied to an element by space-separating the filter functions like this:
.icon:hover {
filter: grayscale(100%) sepia(100%);
}
If one of the filter functions doesn’t exist, or has an incorrect value, the whole list is ignored and no filter will be applied to the element.
When applying multiple filter functions to an element, their order is important and will affect the final output. Each filter function will be applied to the result of the previous operation.
So, in order to colorize our icons, we have to find the right combination.
To make use of hue-rotate()
, we need to start off with a colored icon. The sepia()
filter is the only filter function that allows us to add a color, giving the filtered element a yellow-brown-y tinge, like an old photo.
The output color is dependent on the starting tonal value:
In order to add enough color with sepia()
, we first need to use invert()
to convert our icon to a medium grey:
.icon:hover {
filter: invert(0.5)
}
We can then add the yellow/brown tone with sepia()
:
.icon:hover {
filter: invert(0.5) sepia(1);
}
…then change the hue with hue-rotate()
:
.icon:hover {
filter: invert(0.5) sepia(1) hue-rotate(200deg);
}
Once we have the rough color we want, we can tweak it with saturation()
and brightness()
:
.icon:hover {
filter:
invert(0.5)
sepia(1)
hue-rotate(200deg)
saturate(4)
brightness(1);
}
I’ve made a little tool for this to make your life a little easier, as this is a pretty confusing process to guesstimate.
See the Pen CSS filter example by Cassie Evans (@cassie-codes)
on CodePen.
Even with the tool, it’s still a little fiddly, not supported by Internet Explorer, and most importantly, you’re unable to specify a precise color.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
18* | 35 | No | 79 | 6* |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
109 | 109 | 4.4* | 6.0-6.1* |
So, what do we do if we need a specific hex code?
SVG Filters
If we need more precise control (and better browser support) than CSS filters can offer, then it’s time to turn to SVG.
Filters originally came from SVG. In fact, under the hood, CSS filters are just shortcuts to SVG filters with a particular set of values baked in.
Unlike CSS, the filter isn’t predefined for us, so we have to create it. How do we do this?
This is the syntax to define a filter:
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
...
...
</filter>
...
</defs>
</svg>
Filters are defined by a <filter>
element, which goes inside the <defs>
section of an SVG.
SVG filters can be applied to SVG content within the same SVG document. Or, the filter can be referenced and applied to HTML content elsewhere.
To apply an SVG filter to HTML content, we reference it the same way as a CSS filter: by using the url()
filter function. The URL points to the ID of the SVG filter.
.icon:hover {
filter: url('#id-of-your-filter');
}
The SVG filter can be placed inline in the document or the filter function can reference an external SVG. I prefer the latter route as it allows me to keep my SVG filters tidied away in an assets folder.
.icon:hover {
filter: url('assets/your-SVG.svg#id-of-your-filter');
}
Back to the <filter>
element itself.
<filter id="id-of-your-filter">
...
...
</filter>
Right now, this filter is empty and won’t do anything as we haven’t defined a filter primitive. Filter primitives are what create the filter effects. There are a number of filter primitives available to us, including:
[<feBlend>]
[<feColorMatrix>]
[<feComponentTransfer>]
[<feComposite>]
[<feConvolveMatrix>]
[<feDiffuseLighting>]
[<feDisplacementMap>]
[<feDropShadow>]
[<feFlood>]
[<feGaussianBlur>]
[<feImage>]
[<feMerge>]
[<feMorphology>]
[<feOffset>]
[<feSpecularLighting>]
[<feTile>]
[<feTurbulence>]
Just like with CSS filters, we can use them on their own or include multiple filter primitives in the <filter>
tag for more interesting effects. If more than one filter primitive is used, then each operation will build on top of the previous one.
For our purposes we’re just going to use feColorMatrix
, but if you want to know more about SVG filters, you can check out the specs on MDN or this (in progress, at the time of this writing) article series that Sara Soueidan has kicked off.
feColourMatrix
allows us to change color values on a per-channel basis, much like channel mixing in Photoshop.
This is what the syntax looks like:
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
<feColorMatrix
color-interpolation-filters="sRGB"
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>
</svg>
The color-interpolation-filters
attribute specifies our color space. The default color space for filter effects is linearRGB, whereas in CSS, RGB colors are specified in the sRGB color space. It’s important that we set the value to sRGB in order for our colors to match up.
Let’s have a closer look at the color matrix values.
The first four columns represent the red, green and blue channels of color and the alpha (opacity) value. The rows contain the red, green, blue and alpha values in those channels.
The M column is a multiplier — we don’t need to change any of these values for our purposes here. The values for each color channel are represented as floating point numbers in the range 0 to 1.
We could write these values as a CSS RGBA color declaration like this:
The values for each color channel (red, green and blue) are stored as integers in the range 0 to 255. In computers, this is the range that one 8-bit byte can offer.
By dividing these color channel values by 255, the values can be represented as a floating point number which we can use in the feColorMatrix
.
And, by doing this, we can create a color filter for any color with an RGB value!
Like teal, for example:
See the Pen
SVG filter – teal hover by Cassie Evans (@cassie-codes)
on CodePen.
This SVG filter will only impart color to icons with a white fill, so If we have an icon with a black fill, we can use invert()
to convert it to white before applying the SVG filter.
.icon:hover {
filter: invert(100%) url('assets/your-SVG.svg#id-of-your-filter');
}
If we just have a hex code, the math is a little trickier, although there are plenty of hex-to-RGBA converters out there. To help out, I’ve made a HEX to feColorMatrix converter.
See the Pen
HEX to feColorMatrix converterr by Cassie Evans (@cassie-codes)
on CodePen.
Have a play around, and happy filtering!
DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
SVG is a great format for icons. Vector formats look crisp and razor sharp, no matter the size or device — and we get tons of design control when using them inline.
SVG also gives us another powerful feature: the ability to manipulate their properties with CSS. As a result, we can make quick and simple interactions where it used to take crafty CSS tricks or swapping out entire image files.
Those interactions include changing color on hover states. It sounds like such a straightforward thing here in 2019, but there are actually a few totally valid ways to go about it — which only demonstrates the awesome powers of SVG more.
First off, let’s begin with a little abbreviated SVG markup:
<svg class="icon">
<path .../>
</svg>
Target the .icon
class in CSS and set the SVG fill
property on the hover state to swap colors.
.icon:hover {
fill: #DA4567;
}
This is by far the easiest way to apply a colored hover state to an SVG. Three lines of code!
SVGs can also be referenced using an <img>
tag or as a background image. This allows the images to be cached and we can avoid bloating your HTML with chunks of SVG code. But the downside is a big one: we no longer have the ability to manipulate those properties using CSS. Whenever I come across non-inline icons, my first port of call is to inline them, but sometimes that’s not an option.
I was recently working on a project where the social icons were a component in a pattern library that everyone was happy with. In this case, the icons were being referenced from an <img>
element. I was tasked with applying colored :focus
and :hover
styles, without adjusting the markup.
So, how do you go about adding a colored hover effect to an icon if it’s not an inline SVG?
CSS Filters
CSS filters allow us to apply a whole bunch of cool, Photoshop-esque effects right in the browser. Filters are applied to the element after the browser renders layout and initial paint, which means they fall back gracefully. They apply to the whole element, including children. Think of a filter as a lens laid over the top of the element it’s applied to.
These are the CSS filters available to us:
brightness(<number-percentage>);
contrast(<number-percentage>);
grayscale(<number-percentage>);
invert(<number-percentage>);
opacity(<number-percentage>);
saturate(<number-percentage>);
sepia(<number-percentage>);
hue-rotate(<angle>);
blur(<length>);
drop-shadow(<length><color>);
All filters take a value which can be changed to adjust the effect. In most cases, this value can be expressed in either a decimal or percent units (e.g. brightness(0.5)
or brightness(50%)
).
Straight out of the box, there’s no CSS filter that allows us to add our own specific color.
We have hue-rotate()
, but that only adjusts an existing color; it doesn’t add a color, which is no good since we’re starting with a monochromatic icon.
The game-changing bit about CSS filters is that we don’t have to use them in isolation. Multiple filters can be applied to an element by space-separating the filter functions like this:
.icon:hover {
filter: grayscale(100%) sepia(100%);
}
If one of the filter functions doesn’t exist, or has an incorrect value, the whole list is ignored and no filter will be applied to the element.
When applying multiple filter functions to an element, their order is important and will affect the final output. Each filter function will be applied to the result of the previous operation.
So, in order to colorize our icons, we have to find the right combination.
To make use of hue-rotate()
, we need to start off with a colored icon. The sepia()
filter is the only filter function that allows us to add a color, giving the filtered element a yellow-brown-y tinge, like an old photo.
The output color is dependent on the starting tonal value:
In order to add enough color with sepia()
, we first need to use invert()
to convert our icon to a medium grey:
.icon:hover {
filter: invert(0.5)
}
We can then add the yellow/brown tone with sepia()
:
.icon:hover {
filter: invert(0.5) sepia(1);
}
…then change the hue with hue-rotate()
:
.icon:hover {
filter: invert(0.5) sepia(1) hue-rotate(200deg);
}
Once we have the rough color we want, we can tweak it with saturation()
and brightness()
:
.icon:hover {
filter:
invert(0.5)
sepia(1)
hue-rotate(200deg)
saturate(4)
brightness(1);
}
I’ve made a little tool for this to make your life a little easier, as this is a pretty confusing process to guesstimate.
See the Pen CSS filter example by Cassie Evans (@cassie-codes)
on CodePen.
Even with the tool, it’s still a little fiddly, not supported by Internet Explorer, and most importantly, you’re unable to specify a precise color.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
18* | 35 | No | 79 | 6* |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
109 | 109 | 4.4* | 6.0-6.1* |
So, what do we do if we need a specific hex code?
SVG Filters
If we need more precise control (and better browser support) than CSS filters can offer, then it’s time to turn to SVG.
Filters originally came from SVG. In fact, under the hood, CSS filters are just shortcuts to SVG filters with a particular set of values baked in.
Unlike CSS, the filter isn’t predefined for us, so we have to create it. How do we do this?
This is the syntax to define a filter:
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
...
...
</filter>
...
</defs>
</svg>
Filters are defined by a <filter>
element, which goes inside the <defs>
section of an SVG.
SVG filters can be applied to SVG content within the same SVG document. Or, the filter can be referenced and applied to HTML content elsewhere.
To apply an SVG filter to HTML content, we reference it the same way as a CSS filter: by using the url()
filter function. The URL points to the ID of the SVG filter.
.icon:hover {
filter: url('#id-of-your-filter');
}
The SVG filter can be placed inline in the document or the filter function can reference an external SVG. I prefer the latter route as it allows me to keep my SVG filters tidied away in an assets folder.
.icon:hover {
filter: url('assets/your-SVG.svg#id-of-your-filter');
}
Back to the <filter>
element itself.
<filter id="id-of-your-filter">
...
...
</filter>
Right now, this filter is empty and won’t do anything as we haven’t defined a filter primitive. Filter primitives are what create the filter effects. There are a number of filter primitives available to us, including:
[<feBlend>]
[<feColorMatrix>]
[<feComponentTransfer>]
[<feComposite>]
[<feConvolveMatrix>]
[<feDiffuseLighting>]
[<feDisplacementMap>]
[<feDropShadow>]
[<feFlood>]
[<feGaussianBlur>]
[<feImage>]
[<feMerge>]
[<feMorphology>]
[<feOffset>]
[<feSpecularLighting>]
[<feTile>]
[<feTurbulence>]
Just like with CSS filters, we can use them on their own or include multiple filter primitives in the <filter>
tag for more interesting effects. If more than one filter primitive is used, then each operation will build on top of the previous one.
For our purposes we’re just going to use feColorMatrix
, but if you want to know more about SVG filters, you can check out the specs on MDN or this (in progress, at the time of this writing) article series that Sara Soueidan has kicked off.
feColourMatrix
allows us to change color values on a per-channel basis, much like channel mixing in Photoshop.
This is what the syntax looks like:
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
<feColorMatrix
color-interpolation-filters="sRGB"
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>
</svg>
The color-interpolation-filters
attribute specifies our color space. The default color space for filter effects is linearRGB, whereas in CSS, RGB colors are specified in the sRGB color space. It’s important that we set the value to sRGB in order for our colors to match up.
Let’s have a closer look at the color matrix values.
The first four columns represent the red, green and blue channels of color and the alpha (opacity) value. The rows contain the red, green, blue and alpha values in those channels.
The M column is a multiplier — we don’t need to change any of these values for our purposes here. The values for each color channel are represented as floating point numbers in the range 0 to 1.
We could write these values as a CSS RGBA color declaration like this:
The values for each color channel (red, green and blue) are stored as integers in the range 0 to 255. In computers, this is the range that one 8-bit byte can offer.
By dividing these color channel values by 255, the values can be represented as a floating point number which we can use in the feColorMatrix
.
And, by doing this, we can create a color filter for any color with an RGB value!
Like teal, for example:
See the Pen
SVG filter – teal hover by Cassie Evans (@cassie-codes)
on CodePen.
This SVG filter will only impart color to icons with a white fill, so If we have an icon with a black fill, we can use invert()
to convert it to white before applying the SVG filter.
.icon:hover {
filter: invert(100%) url('assets/your-SVG.svg#id-of-your-filter');
}
If we just have a hex code, the math is a little trickier, although there are plenty of hex-to-RGBA converters out there. To help out, I’ve made a HEX to feColorMatrix converter.
See the Pen
HEX to feColorMatrix converterr by Cassie Evans (@cassie-codes)
on CodePen.
Have a play around, and happy filtering!
DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
There are a lot of different ways to use SVG. Depending on which way, the tactic for recoloring that SVG in different states or conditions — :hover
, :active
, :focus
, class name change, etc. — is different.
Let’s look at the ways.
Inline SVG
Inline SVG is my favorite way to use SVG anyway, in part because of how easy it is to access and style the SVG.
See the Pen
bJXNyy by Chris Coyier (@chriscoyier)
on CodePen.
If you’re used to working with icon fonts, one thing you might enjoy about them is how easy it is to change the color. You’re largely limited to a single color with icon fonts in a way that SVG isn’t, but still, it is appealingly easy to change that single color with color
. Using inline SVG allows you to set the fill
, which cascades to all the elements within the SVG, or you can fill each element separately if needed.
SVG Symbol / Use
There is such thing as an SVG sprite, which is a group of SVGs turned into <symbol>
elements such that any given icon can be referenced easily with a <use>
element.
See the Pen
Use SVG Hovers by Chris Coyier (@chriscoyier)
on CodePen.
You can still set the fill color from outside CSS rather easily this way, but there are caveats.
- The internal SVG elements (like the
<path>
) can have no fill themselves. This allows the fill set from the parent SVG to cascade into the Shadow DOM created by<use>
. As soon as you have something like<path fill="blue" ... />
in the<symbol>
, you’ve lost outside CSS control. - Likewise, the
fill
of individual elements cannot be controlled within the SVG like you could with inline SVG. This means you’re pretty firmly in single-color territory. That covers most use cases anyway, but still, a limitation nonetheless.
SVG background images
SVG can be set as a background image just like PNG, JPG, or whatever other graphics format. At this point, you’ve sort of given up on being able to change the fill
. One possibility, which I’d argue isn’t a particularly good one, is to have two versions of every icon, in the respective colors, and swap between them:
See the Pen
Background SVG Hovers by Chris Coyier (@chriscoyier)
on CodePen.
I don’t blame you if you’d rather not swap sources, so another possibility is to get gnarly with filters.
See the Pen
Background SVG Hovers with Filters by Chris Coyier (@chriscoyier)
on CodePen.
Trying to finagle the right filters to get the color right is tricky stuff. Fortunately, Barrett Sonntag made a tool to calculate the filters for you! Turning black to red ends up a whacky combination like this: invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);
.
SVG also has object
, which is kinda neat in that it had a built-in fallback back in the day — although browser support is so good these days, I honestly have never used it. But if you’re using it, you would probably have to use this filter
technique to swap color on hover.
See the Pen
Background SVG Object Hovers by Chris Coyier (@chriscoyier)
on CodePen.
Use a mask instead of a background image
This way, the SVG is still in charge of essentially drawing the shape, but the color comes from the background-color
(or image! or gradient!) behind it rather than the SVG itself.
See the Pen
Background SVG Hovers with Mask by Chris Coyier (@chriscoyier)
on CodePen.
SVG background images as data URLs
This doesn’t change that much from above, but it does open up one interesting possibility: Using a variable for the internal fills. Here that is with Sass keeping the URLs as variables:
See the Pen
Background SVG Hovers with Data URL variables by Chris Coyier (@chriscoyier)
on CodePen.
You can also do this with native CSS custom properties!
#База знаний
- 5 мар 2021
-
14
Узнаём про векторную графику, добавляем svg-картинки к HTML и творим всякое-разное с их цветом.
Автор статей по программированию. Преподаватель, ментор, выпускник Skillbox. Фрилансер, веб-разработчик
Помимо привычных растровых форматов (JPG, PNG, GIF), в веб-разработке широко применяют векторный — SVG.
SVG (сокращение от Scalable Vector Graphics — «масштабируемая векторная графика») — это вид графики, которую создают с помощью математического описания геометрических примитивов (линий, кругов, эллипсов, прямоугольников, кривых и так далее), которые и образуют все детали будущего изображения.
То есть в этом формате хранится не сама картинка, а инструкции для её построения по точкам и кривым. Они написаны на языке разметки SVG, расширяющем XML.
Прелесть SVG раскрывает масштабирование. Если увеличить растровое изображение сверх 100%-ного размера — проявляется пикселизация: отдельные точки превращаются в одноцветные блоки пикселей, границы областей становятся ступенчатыми, и в целом картинка выглядит негладко, некрасиво.
Если же увеличить векторное изображение — все его детали останутся чёткими, то есть их видимое разрешение не уменьшится. Поэтому svg-картинки отображаются на самых больших разрешениях без потери качества — и просто идеальны для адаптивных сайтов.
У svg-графики есть ещё одно достоинство. Её можно открывать как HTML или CSS и менять в любом редакторе кода, и даже на лету. Подробнее об этом ниже.
И наконец, при прочих равных SVG весит намного меньше растровых изображений.
Их мало. Во-первых, SVG не поддерживается очень старыми браузерами, а во-вторых, не используется для фотографий.
Есть три варианта добавления векторной графики. У каждого свои показания к применению.
Здесь всё так же, как и с растровой графикой:
<img src="img/icon.svg" alt="Иконка лупы">
Минус этого способа в том, что взаимодействовать с внутренними элементами SVG не получится. Файл будет как за стеклом: смотреть можно, а вот трогать нельзя.
Такой вариант подключения используется для контентных svg-изображений, которые менять внешне не требуется (вроде графиков, схем и логотипов).
Как и в случае с растровой графикой, SVG можно подключать через css-свойство background:
.icon {
background-image: url("../img/icon.svg");
}
Минус тут тот же самый, что и у предыдущего способа. Этот случай подходит для декоративных изображений (фоны, иконки и прочая мелочь), которые тоже внешне менять не нужно.
Вставлять svg-код прямо в html-файл — это третий способ. И для нас самый интересный. Он позволяет не просто отображать готовую графику, но и менять её (толщину элементов, заливку, обводку и так далее).
<svg>
<rect x="10" y="10" width="100" height="100" />
</svg>
Такая вставка выручает, когда при взаимодействии с картинкой нужно её визуально модифицировать — например, перекрасить svg-иконку при наведении на неё курсора.
Напрямую на html-страницу (в теге <svg>) вставляют как контентные, так и декоративные изображения, а минус тут в том, что такие картинки не кешируются отдельно от страницы.
Верстальщику часто приходится обыгрывать реакцию иконки при наведении на неё мышки. В случае с svg-картинками можно просто менять их цвет.
Научимся это делать на примере иконки «ВКонтакте»:
Логотип сложный, поэтому svg-код, который его математически описывает, довольно длинный. Посмотрим, как это выглядит в HTML:
<a href="https://vk.com/" class=”vk”>
<svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512"
xmlns="http://www.w3.org/2000/svg">
<path d="m19.915 13.028c-.388-.49-.277-.708 0-1.146.005-.005 3.208-4.431 3.538-5.932l.002-.001c.164-.547 0-.949-.793-.949h-2.624c-.668 0-.976.345-1.141.731 0 0-1.336 3.198-3.226 5.271-.61.599-.892.791-1.225.791-.164 0-.419-.192-.419-.739v-5.105c0-.656-.187-.949-.74-.949h-4.126c-.419
0-.668.306-.668.591 0 .622.945.765 1.043 2.515v3.797c0 .832-.151.985-.486.985-.892
0-3.057-3.211-4.34-6.886-.259-.713-.512-1.001-1.185-1.001h-2.625c-.749 0-.9.345-.9.731
0 .682.892 4.073 4.148 8.553 2.17 3.058 5.226 4.715 8.006 4.715 1.671 0 1.875-.368 1.875-1.001
0-2.922-.151-3.198.686-3.198.388 0 1.056.192 2.616 1.667 1.783 1.749 2.076 2.532 3.074
2.532h2.624c.748 0 1.127-.368.909-1.094-.499-1.527-3.871-4.668-4.023-4.878z" />
</svg>
</a>
Да, это не ошибка, так в HTML вставляют небольшие svg-картинки. Для больших целесообразнее подключать отдельный файл, который будет кэшироваться браузером. Здесь мы не будем в это углубляться.
Обратите внимание на тег <path> (в переводе с английского «путь»). Он позволяет задать любую фигуру компактной строкой — описанием пути от начальной точки до конечной через промежуточные координаты.
Строка с данными задаётся атрибутом d тега <path>. Она содержит команды, которые закодированы набором букв и чисел. Буква представляет тип команды, а числа — её параметры (чаще всего координаты).
Теперь мы запросто добавим к ссылочному тегу <a> псевдокласс :hover и зададим через него новый цвет svg-изображения. Это делается в CSS с помощью свойства fill («заливка»).
.vk:hover svg {
fill: red;
}
Проверьте, как это работает: наведите курсор на иконку — например, в песочнице Codepen.
И ещё один нюанс. Заливка может быть задана атрибутом у <svg> (fill=»#000″). Тогда работать с ней через CSS не получится, так как css-стили не могут перебить правила, заданные атрибутами. В этом случае стоит просто вручную удалить этот атрибут у <svg>.
Итак, мы научились менять цвет svg-иконки через свойство fill, вставляя её напрямую в HTML. Заметьте, что такое нельзя сделать ни с помощью тега <img>, ни через свойство background.
Рассмотрим более сложную ситуацию — когда иконка состоит из нескольких простых svg-изображений. Например, примитивная лупа из прямоугольника и круга:
Код для кнопки с иконкой лупы будет таким:
<button class="btn-reset search">
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="19.5138" y="18.5495" width="8" height="2" transform="rotate(45 19.5138 18.5495)"
/>
<circle cx="11.5" cy="11.5" r="10.5" stroke-width="2" />
</svg>
</button>
Проблема здесь в том, что внутри svg-иконки два разных тега:
- <rect> (прямоугольник — ручка лупы)
- и <circle> (круг — ободок лупы).
Сделать как в примере с «ВКонтакте» не получится, потому что прямоугольник в нашем случае имеет заливку (fill), а круг — обводку (stroke).
Чтобы при наведении менять цвет обоих, используем два селектора. Один будет менять заливку у палочки, второй — обводку у круга:
.search svg rect {
fill: #000;
}
.search svg circle {
stroke: #000;
}
.search:hover svg rect {
fill: yellow;
}
.search:hover svg circle {
stroke: yellow;
}
Как видите, при наведении на кнопку мы сперва нашли rect, потом circle, то есть разделили логику.
Делить код таким образом приходится нечасто, но помнить об этой возможности полезно.
Например, поучитесь работать с фоновыми картинками через CSS.
Учись бесплатно:
вебинары по программированию, маркетингу и дизайну.
Участвовать
Школа дронов для всех
Учим программировать беспилотники и управлять ими.
Узнать больше
На чтение 6 мин Просмотров 10.8к. Опубликовано 22.04.2021
Содержание
- В предыдущих сериях…
- Где взять inline код SVG-иконки
- Содержимое svg кода
- Теги
- Атрибуты
- Интерактив по ховеру
- Заключение
В предыдущих сериях…
Ранее мы выяснили, в чем отличие растровых форматов изображения от векторных. И научились подключать SVG-иконку на сайт тремя способами.
Сегодня будем работать с inline кодом, посмотрим, какие бывают атрибуты у тега <svg>
. Разберем случай, почему может не работать смена цвета иконки, прописанная в файле CSS.
Где взять inline код SVG-иконки
Если вы скачали готовую графику в формате .svg, то этот файл можно открыть в любом редакторе кода и увидеть тот самый inline код. Как мы помним, векторная графика описывает изображение с помощью специальных формул для создания фигур. При этом используются тег <svg>
(контейнер для хранения SVG графики), внутри которого помещается один или несколько тегов <path>
(для хранения координат прорисовки фигуры или части её). Этот код можно скопировать и вставить в html файл в том месте, где нужно расположить иконку.
Для примера возьмем иконку твиттера. Скопируем тег svg
из файла иконки и вставим в HTML.
Содержимое svg кода
Итак, мы подключили иконку в формате svg
inline, теперь рассмотрим код подробнее.
<h2>Пример inline кода</h2> <!-- Twitter icon --> <svg class="twitter-icon" width="256" height="256" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/> </svg>
Так отобразится в браузере:
Пример inline кода
Теги
Мы видим тег <svg>
и <path>
, у которого есть атрибут d
с координатами точек на плоскости, по которым рисуется фигура. В данном случае тег <path>
один, изображение состоит из одной фигуры, но изображение может состоять из нескольких фигур — тогда будет несколько тегов <path>
.
Атрибуты
Перейдем к атрибутам тега <svg>
xmlns="http://www.w3.org/2000/svg"
— данный атрибут прописывает путь к стандарту svg, в котором описана эта иконка
viewBox="0 0 512 512"
— указывает на ту область иконки, которую мы видим в браузере
class="twitter-icon"
— как и другим элементам, можно задать класс и стилизовать по нему в CSS файле
Теперь добавим некоторые атрибуты самостоятельно.
<h2>Пример inline кода с атрибутами</h2> <!-- Twitter icon --> <svg class="twitter-icon" width="256" height="256" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="red" stroke="green" stroke-width="10" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/> </svg>
width="256" height="256"
— при помощи этих атрибутов можно настраивать размер иконки
Атрибуты fill
, stroke
, stroke-width
в SVG
Эти атрибуты можно применить к тегу <svg>
и тогда они распространятся на всю иконку. А можно применить к отдельному <path>
— тогда они будут работать только в области, описанной в конкретном <path>
. В нашем случае иконка состоит всего из одного <path>
, поэтому без разницы, к чему применить данные атрибуты.
fill="red"
— заливка цветом
stroke="green"
— цвет обводки
stroke-width="10"
— толщина обводки
Вот так мы переделали иконку при помощи атрибутов:
Пример inline кода с атрибутами
Интерактив по ховеру
При помощи CSS будем менять поведение иконки при наведении на нее курсором (по ховеру). Вернемся к изначальному коду без дополнительных атрибутов. Копируем класс иконки и стилизуем в файле CSS. Зададим свойство fill: blue;
и далее по псевдоклассу :hover
меняем на fill: rgb(145, 8, 199);
HTML
<h2>Пример inline кода, стилизация в CSS</h2> <!-- Twitter icon --> <svg class="twitter-icon" width="256" height="256" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/> </svg>
CSS
/* Интерактив. SVG inline код. Смена цвета по ховеру */ .twitter-icon { fill: blue; } .twitter-icon:hover { fill: rgb(145, 8, 199); }
Результат в браузере:
Пример inline кода, стилизация в CSS
Внимание!
Этот прием будет работать только в том случае, если в html коде фигуры не прописан нигде атрибут fill=""
. Если вы работаете в CSS, то лучше убирать все атрибуты типа fill
и stroke
, чтобы не было путаницы. И переносить их в файл CSS в качестве свойств.
Заключение
Любой файл .svg
можно открыть в редакторе кода. Сам код можно копировать и использовать в файле .html
Кастомизировать иконку можно при помощи атрибутов. Но создать интерактивность получится только при помощи стилизации в CSS файле. При этом важно следить за тем, чтобы контроль заливки или других свойств, которые будут меняться, происходил только в одном месте, в файле .css
. В противном случае интерактив не заработает, так как значения атрибутов перебьют значения свойств.
🗓️ Обновлено: 09.08.2022
💬Комментариев:
0
👁️Просмотров: 15921
В этой статье рассмотрим несколько примеров, как задать цвет любому изображению в формате svg с использованием css-стилей.
Есть множество вариантов, как использовать SVG. От того, как вы применяете SVG и будет зависеть способы редактирования.
Давайте начнем с базы.
Основы
Что такое SVG?
SVG (Scalable Vector Graphic) — масштабируемая векторная графика. Это уникальный формат для изображений. В отличии от привычных нам форматов, в svg не используются пиксели. Здесь картинка строется на векторах. Это значит, что вы можете, например, масштабирать размер картинки до любых значений и при этом не терять качество.
Изображение svg можно вставить кодом прямо в файл html — это будет инлайновый вариант:
<div class="svg-inline">
<svg enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m12 24c6.629 0 12-5.371 12-12s-5.371-12-12-12-12 5.371-12 12 5.371 12 12 12zm-6.509-12.26 11.57-4.461c.537-.194 1.006.131.832.943l.001-.001-1.97 9.281c-.146.658-.537.818-1.084.508l-3-2.211-1.447 1.394c-.16.16-.295.295-.605.295l.213-3.053 5.56-5.023c.242-.213-.054-.333-.373-.121l-6.871 4.326-2.962-.924c-.643-.204-.657-.643.136-.953z"/></svg>
</div>
А можно вставить через тег img:
<div class="svg-inline">
<img src="img/icon.svg" alt="Svg" width="24">
</div>
Если заглянуть «под капот» и изучить код, который отвечает за отрисовку SVG, то можно выделить два свойства, которые отвечают за цвет — fill (заливка) и stroke (обводка). Их можно редактировать и тем самым менять цвет иконки.
Давайте выделим несколько методов, которые позволяют менять цвет SVG.
1. Меняем цвет с помощью свойства fill
Смотрите, у нас два квадрата — они идентичны, за исключением свойства fill. В одном случае мы залили квадрат красным цветом, в другом вообще не прописали это свойство.
Свойство fill можно применять к отдельному вектору в вашем изображении.
2. Меняем цвет в файле style.css
Или в любом другом файле css, который подключен к html.
Все легко и понятно. Мы обращаемся к тегу svg и с помощью свойства fill меняем цвет на тот, который нам нужен.
svg {
fill: #5046e5;
}
Можете задать svg нужный класс и затем в css обратиться к элементу по этому классу:
<svg class="arrow-svg" width="24" height="24" viewBox="0 0 24 24">...
.arrow-svg {
fill: #5046e5;
}
Это тоже будет работать.
ВАЖНО!
Такой метод будет работать, если вы вставите код svg прямо в файл html.
Если вставить svg, как картинку в тег img, то изменить цвет не получится. В таком случае подойдет вариант №1, который был описан выше.
3. Изменяем цвет с помощью инлайновых стилей
Мы можем прямо в файле svg прописать стили — с помощью <style></style>:
<svg
width="120"
height="120"
viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<style>
rect {
fill: red;
}
</style>
<rect x="10" y="10" width="100" height="100"/>
</svg>
Внутри тега svg мы вставили обычные инлайновые стили. Обратите внимание, здесь мы обращаемся к тегу rect, но мы легко можем добавить класс нашему квадрату и обращаться к нему через класс:
<rect x="10" y="10" width="100" height="100" class="someclass" />
Так же, с помощью инлайновых стилей можем менять цвет svg при наведении. Это должно быть вам знакомо.
<style>
rect:hover {
fill: red;
}
</style>
Это же актуально и для метода №2.
Краткий вывод
Если вы используете инлайновый вариант вставки SVG в ваш код, то вы сможете с помощью CSS редактировать цвет изображения. Но если вы вставляете svg, как файл через img или как background-url, то добраться до свойств SVG с помощью CSS у вас не выйдет.
На этом все, если остались вопросы, то задавайте в комментариях. Мы отвечаем на все ваши вопросы.