Css svg fill on hover. Styling SVG with CSS: Features and Limitations


SVG is new standard vector images in the browser. Vector editors, such as Adobe Illustrator, allow you to directly save graphics in this format, and modern browsers display SVG without problems.

Because the SVG images consist of markup and can be created and maintained using your favorite text editor, just as you would with HTML. Moreover, you can even style SVG with using CSS, although you will need to become familiar with the differences between SVG and HTML styling.

SVG attributes and CSS properties

The line between HTML and CSS is clear. HTML is responsible for content and structure, CSS for display. In SVG this line is blurred, to say the least. This main reason that text boxes and shapes are usually controlled using element attributes rather than CSS:

In this example, we draw a rectangle that is filled using the fill attribute. The color and width of the rectangle's outer border are specified by the stroke and stroke-width attributes. But you can also style the rectangle like this using CSS:

We simply used attributes as CSS properties. Although, this does not work for all attributes. You cannot set the position and width and height values ​​this way. We'll just use the y attribute, as well as width and height.

Just like in HTML, we can work with classes or identifiers of any element. So we would define a representation for a set of SVG elements through a styled class.

Because SVG does not differentiate between the head and body regions, style sheets and the content itself share the SVG element, which is comparable to the HTML element.

Using Pseudo-Classes

SVG allows the use of pseudo-classes such as:hover , even in conjunction with the CSS3 transition property.

Having implemented this example, we will see that when we hover over an element with the example class set for it, the fill color will change from red to blue. For this to work properly, don't embed the SVG using img tag. Better use embed or iframe:

When using the img tag, the SVG itself will display correctly. But hover effects and transitions will be ignored. In addition to the transition property, we can also use transform . In this case, the elements will be scaled or rotated.

When using CSS3, be sure to add vendor prefixes to ensure support for as many as possible modern browsers. While Chrome and Firefox handle rendering flawlessly, Internet Explorer refuses to show your creation, although it is perfectly capable of showing these CSS3 properties if you apply them to HTML.

Media queries and SVG

If you want to customize your SVG to adapt to specific resolutions, just use media queries right inside it:

In this example, elements that have the example class specified will not be shown as soon as the visible screen width becomes less than 800 pixels. Be careful, this is not about the width of the document, but about the width of the SVG carrier element.

SVG is the new standard for vector images in the browser. Vector editors such as Adobe Illustrator allow you to directly save the file to this format, and modern browsers have no problem displaying SVG correctly. Since SVG graphics are made up of markup, they can be created and modified in your favorite text editor, which you are using for HTML. It's even possible to style SVG using CSS, but there are a few subtleties here.

The dividing line between HTML and CSS is pretty straight. HTML is responsible for the content and structure, and CSS takes care of the appearance of the projects. In SVG this line is blurred. This is the main reason why text and shapes in SVG are typically controlled using element attributes rather than CSS:

In this example we have drawn a rectangle which is filled in using fill . The color and strength of the outer rectangle frame is determined by the attributes stroke and stroke-width.. But, the rectangle can be styled in the same way using CSS:

However, this does not work for all attributes. You won't be able to define positions and values ​​for width and height this way. We'll just stick with the y , width and height attributes.

Just like in HTML, we could work with classes and IDs on any element. So we would ask appearance multiple elements in SVG using a styled class.

Using Pseudo-Classes

Using pseudo-classes such as:hover is possible in SVG, even in combination with the CSS3 transition property.

By implementing this example, hover elements carrying the example class will cause the color to change from red to blue. For this to work properly, make sure the SVG is not inserted as an Img. Better choose Embed or Iframe:

Using Img will help display the SVG properly. But, hover effects and transitions will be ignored. In addition to transition, we could use transform, thereby allowing elements to be scaled or rotated.

When using CSS3, be sure to add vendor prefixes to support as many modern browsers as possible. While Chrome and Firefox have no problem rendering flawlessly, Internet Explorer will refuse to show your creations even in the most latest version, while it is perfectly capable of showing these CSS3 properties when used in HTML.

Media queries and SVG

If you want to customize your SVG so that it can change sizes, then just use media queries directly in it:

This example ensures that elements of class example will not be shown as soon as the visible width drops below 800 pixels. Be aware that it is not the width of the document that determines this, but the width of the element carrying your SVG.

In this example, elements of the example class will not be shown, since the specified width is only 500 pixels. Media queries in SVG are also useful for optimizing graphics for printing.

Today, there is more than one way to create SVG animation. This can be done using a tag that is inserted directly into the SVG code. There are special libraries such as Snap.svg or SVG.js.

We'll take a slightly different approach: using inline SVG (SVG code directly in the HTML) and animating individual parts directly through CSS.

I recently experimented with this method, in a project for my alma mater Wufoo, as a bit of a refresher on the topic we'll be covering here.

I haven't used SVG much in my recent projects, so I think this article is a great opportunity to give it more attention.

The final animation look is very simple. Here's what it looks like:

View on CodePen

Let's look at how this is done.

1. Make a list of elements that we will use

It may seem that there is a lot of work here in the manner of how to draw an owl, but this article is about animation, so let's deal with graphics as quickly as possible.

My plan was to make a super simple Wufoo ad using their classic logo, colors and corporate identity. And then add a little creativity:

  1. Create the effect that the letters are running off the page. Wufoo is a fun word, let the letters be fun too;
  2. The day before, we designed a T-shirt with a dinosaur on the front and the words on the back: “ Fast. Smart. Grozny" These are traits that both dinosaurs and Wufoo share. Not to mention the fact that we played on the word “FORMidble” (formidable). So I wanted to make these words appear and disappear in the animation block;
  3. To connect these words with a dinosaur, we will have the T-Rex's head appear and then quickly disappear. This will display the word “Fast”, which will be another interesting link for the elements.
  4. I loaded all these elements into Illustrator:

Notice how the logo and slogan texts are outlined. This means that they are simply vector shapes, and effects can be easily applied to them, both in SVG and in

The text you see is “Fast. ” remains in Illustrator in text format.

When I save the file in Illustrator, the lettering will remain an element.

2. Save in SVG format

Illustrator supports saving as SVG:


You can open this SVG file in a code editor and see the SVG code in it:


3. Clean up the SVG and set classes for the shapes

You can run the code through SVGO to optimize it and remove unnecessary elements like DOCTYPE and the like.

But now it’s more important for us to ask different names classes for shapes, so we can select them in CSS and do different things!

4. Insert SVG

You can copy this SVG code and paste it directly into the HTML where you want the block to appear. But this is just a primitive template.

You can do something like this:

...

5. Animation!

Now all these shapes are captured in the DOM, and we can position them and style them just like any other HTML element. Let's do that.

Let's say we want to use a 10 second timeline:

First words fall out and disappear

The first thing we want to do is print the words " Fast. Smart. Grozny.» Each word will be displayed for one second.

This is how we create an animation in which each word takes 10% of the time:

@keyframes hideshow ( 0% ( opacity: 1; ) 10% ( opacity: 1; ) 15% ( opacity: 0; ) 100% ( opacity: 0; ) )

Then we specify the first word and the duration of the entire animation at 10 seconds (10% of which is 1 second):

Text-1 ( animation: hideshow 10s ease infinite; )

The next two words will be hidden first (opacity: 0; ), and then we will use the same animation, only with a time delay, so that the next words will appear a little later:

Text-2 ( opacity: 0; animation: hideshow 10s 1.5s ease infinite; ) .text-3 ( opacity: 0; animation: hideshow 10s 3s ease infinite; )

An additional 0.5 seconds is needed to set the interval between the output of each next word.

Jumping letters

Once we have set the animation for this element, we proceed to the effects for the letters in the word Wufoo, which should jump to the side like this:

The trick here is that we create an animation effect that only lasts 5 seconds, but we run it forward once and then backward.

So it will correspond to our 10 second chart, and will be located in the middle of the timeline. All we have to do is set the parameters for scrolling the animation effect in one direction, because when reverse scroll it will simply return to its original position.

The effects for each letter have a slight time delay, so they do not all move at the same time, but one after the other:

Wufoo-letter ( animation: kaboom 5s ease alternate infinite; &:nth-child(2) ( animation-delay: 0.1s; ) &:nth-child(3) ( animation-delay: 0.2s; ) &:nth- child(4) ( animation-delay: 0.3s; ) &:nth-child(5) ( animation-delay: 0.4s; ) ) @keyframes kaboom ( 90% ( transform: scale(1.0); ) 100% ( transform : scale(1.1); ) )

The SCSS code above is just a short version, it does not include prefixes (which you will need in practice).

I think animation-delay is a property that would be useful to take from original CSS. It would look neater when the letters move with a slight delay.

And finally, the dinosaur

After these inscriptions flash across the block, a dinosaur’s head emerges from below. Despite the fact that the dinosaur figure consists of large quantity elements, we can position them all together using a positioning tag (group), which contains all these elements.

Since it's more efficient to use transforms to position the animation, we'll do this using keyframes :

@keyframes popup ( 0% ( transform: translateY(150px); ) 34% ( transform: translateY(20px); ) 37% ( transform: translateY(150px); ) 100% ( transform: translateY(150px); ) )

We want this animation to be displayed in the "last" approximately 3 seconds. This cycle actually works for the entire 10 seconds, but you will see the actual visible effects during the last 3 seconds.

When translateY(150px) is applied in the effect, the dinosaur moves so far down outside the box that you can't see it.

But for 37% of the time of this animation (about 3 seconds) you see him slowly moving up and then quickly moving back down.

When we apply this animation we will make sure that:

  • The dinosaur is hidden at first;
  • The output of this animation fragment is delayed in time, so it begins immediately after the letters in the logo word have finished their dance (they have shifted to the side and returned to their place).

Trex ( transform: translateY(150px); animation: popup 10s 6.5s ease infinite; )

The dinosaur falls down just at the last second so that immediately afterwards the word “Fast” appears in the block again (the animation playback interval is set to infinite so that it runs in a circle over and over again). It adds some fun synergy.

6. Making the block a clickable/interactive ad

One of useful features SVG is the ability to scale objects to any size without losing quality.

To create an inline SVG box while maintaining the original quality of the images, we can use the ol' padded box technique.

...
.wufoo-ad-wrap ( height: 0; padding-top: 100%; position: relative; ) .wufoo-ad ( position: absolute; top: 0; left: 0; width: 100%; height: 100%; )

The idea is that the “wrapper” will always take the shape of a square, based on its width. Then we ask absolute values SVG positions inside this perfect square, the dimensions of which are adjusted based on the width.

Since this is an ad (which, of course, needs to be clickable), then as the containing container, instead of

, you can use , just make sure you set it as display: block; .

Detailed article on styling content in an SVG element and overcoming related problems.

Graphics in the SVG format are especially often used to create icons, and one of the most common techniques for this is SVG sprites using SVG use to instantiate icons in the right place in the document.

Instantiating icons or any other SVG content into an element causes difficulties when designing individual copies. The purpose of this article is to give you an overview of some possible ways bypass design restrictions associated with use .

But before we begin, let's quickly look at the basic structure and grouping of elements in SVG, gradually moving on to , DOM, and then back to the CSS. We will look at why the design can cause difficulties and how to overcome them.

A quick overview of SVG structure, grouping, and element referencing in SVG

SVG includes 4 basic elements to define, structure, and link to SVG content in a document. These elements allow images to be reused while keeping the code readable and maintainable. Due to the nature of SVG, some of these elements have functionality similar to the corresponding commands in graphics editors.

The 4 main grouping and linking elements of SVG are: , , and .

Element (short for “group”) is used to logically group together sets of related graphic elements. In terms of graphic editors (such as Adobe Illustrator), the element Its functionality is similar to the “Group objects” function. You can also think of a group as a layer in a graphics editor.

Grouping elements is useful in cases where you want to apply a style to all elements of a group, and also when you want to animate all elements of a group while maintaining the relationship between them.

Element is used to define many things, mainly defining patterns such as gradients, which can then be used to fill other SVG elements. It can be used to define any elements that you are going to use anywhere on the canvas.

Element combines possibilities And one that is used to group elements together to create a pattern that can be referenced elsewhere in the document. Unlike , not used to set patterns; it is typically used to create symbols such as icons, which are then used throughout the document.

At the element There is another important advantage: it accepts a viewBox attribute, which allows zooming within any scope.

Element allows you to use a previously defined element anywhere in the document. It allows you to reuse elements and provides functionality similar to copy-paste in a graphics editor. It can be used either as a single element or as a group specified in , or .

To use an element you need to pass a link to this element, the identifier is the xlink:href attribute and position it by setting the x and y attributes. You can apply styles to an element and they will cascade onto the content of this element.

But what is the content? ? Where does it clone? And how does CSS cascade work with it?

Before we answer these questions, and given that we've only had a quick look at SVG structure and grouping, it's worth mentioning a couple of articles that will let you learn more about these elements, as well as the viewBox attribute on an element :

  • Structuring, Grouping and Linking in SVG - The g, use, defs and symbol elements
  • Understanding the SVG coordinate system (Part 1): Viewport, viewBox and PreserveAspectRatio

SVG and shadow DOM

When you refer to an element with , your code looks something like this:

An icon is displayed on the screen, the contents of which are defined internally , but it's actually the content of the element , which is a clone .

But the element it's just one self-closing element - there's no content between the opening and closing tags, so where does the content get cloned? ?

The answer is in shadow DOM(for some reason I always associate him with Batman, I don’t know why).

What is shadow DOM?

The shadow DOM is identical to the regular DOM, except that instead of being part of the main document tree, shadow DOM nodes refer to a fragment of the document that is parallel to the main document, but is not accessible to its scripts and styles. This gives authors the ability to create modular components by encapsulating scripts and styles. If you've ever used a video element or range input in HTML5 and didn't understand where the video player or slider controls came from, then the answer is the same - the shadow DOM.

In the case of an SVG element , the content it refers to is cloned into a document fragment “hosted” in . IN in this case this is a shadow host.

So the contents (clone or copy of the element it refers to) is present inside the shadow document fragment.

In other words, the content is there, but it is invisible. The same as the contents of the regular DOM, but not accessible to high-level features such as CSS and JavaScript selectors, copied into a document fragment bound to .

Now, if you're a designer, you might be thinking, "OK, I get it, but is there a way to inspect this subdocument and see its contents." The answer is yes, you can view the contents of the shadow DOM using the development tools in Chrome (in Firefox on this moment this function is not available). But first, you need to activate the shadow DOM inspector in the General tab of the settings panel. This is described in detail.

Once you've enabled Shadow DOM Inspection in Developer Tools, you can see cloned elements in the Toolbox, just like regular DOM elements. The following image shows an example element , referencing the content of the element . Please note that “#shadow-root” and its contents are a clone of the contents .

Using Chrome Developer Tools, you can inspect the contents of the use element inside the shadow DOM (“#shadow-root”, line highlighted gray). This screenshot inspects the Codrops logo from the example we'll look at in the next section.

Looking at the inspected code, you can see that the shadow DOM is very similar to the regular DOM, except for the way it is handled by the CSS and JavaScript of the main document. There are also other differences between the two that we won't cover in this article due to length, so if you want to learn more, I recommend the following articles:

  • Shadow DOM 101 (translated by Frontender.info)
  • Introduction to Shadow DOM (Video)

Given my limited experience with the shadow DOM, I view it as a regular DOM that needs to be handled differently in terms of CSS and JavaScript access to its elements. This is what is important to us when working with SVG: how to influence the content inside the shadow DOM, because it is important for us to be able to style it. The whole point of using this is the ability to create different copies of an element and in most cases we need to be able to style each copy differently. For example, this could be a logo in two color themes or multi-color icons for different color themes. So it's important for us to be able to do this with CSS.

As stated, the contents of the shadow DOM are not accessible to CSS, unlike the regular DOM. So how do we style it? We can't use a descendant path like this:

Use path#line ( stroke: #009966; )

Because we don't have access to the shadow DOM using regular CSS selectors.

You might expect, as I do, that presentational attributes have the highest specificity of all style rules. After all, external styles are usually overwritten by internal declarations, and these, in turn, are overwritten by inline attribute styles - they have maximum specificity, and, accordingly, priority over other styles. While this expectation makes sense, the actual mechanism at work is different.

In fact, presentational attributes are treated as low-level “author style sheets” and they are overwritten by other style declarations: external, internal and inline styles. Their only strength is their priority over inherited styles. That's all.

Now that we have that cleared up, let's go back to our element and its contents.

We know that we can't set styles internally using CSS selectors.

But we also know that, as with the element , styles applied to will be inherited by all of its descendants (which are in the shadow DOM).

So, first let's try to change the fill color of the element inside by applying the selector to the element itself with the expectation that cascade and inheritance will do their job.

However, this raises a couple of questions:

  1. The fill color will be inherited all descendants element , even ones you don't want to apply styles to (but if inside If you have only one element, then this problem will not occur).
  2. If you exported SVG from graphic editor or are otherwise unable to modify the SVG code, then you will end up working with SVG that already has presentational attributes applied to it (unless you explicitly override this when exporting to SVG format) and the values ​​of those attributes will take precedence over inherited from .

And even if you can edit the SVG code and can get rid of them, I strongly recommend not to do so for the following reasons:

  1. Removing attributes in order to subsequently set certain properties will reset the values ​​of these properties to the default, and this is, as a rule, a black fill and stroke (in relation to colors).
  2. By resetting values, you force yourself to style the entire set of properties.
  3. Presentation attributes, which are initially set, are an excellent fallback in case of problems with external styles. If the CSS doesn't load, your icons will still look nice.

So we have these attributes, but we want to style different instances of the icons differently.

This is done by forcing the presentation attributes to inherit the styles specified or finding a way around overriding these values. To do this, we will have to use the full power of CSS cascading.

Let's start with simple examples and gradually move on to complex ones.

Rewriting presentation attribute values ​​using CSS

Presentation attributes are overridden by any style declaration. We can use this to ensure that the presentation attribute receives a value inherited from the styles .

This is easy thanks to the CSS inherits keyword. Take a look at next example- an ice cream icon drawn with one outline, the color of which we want to change in different instances. The icon was created by Erin Agnoli from Noun Project.

The content of our ice cream icon (path) is defined inside the element , which means that it will not be displayed on the canvas by default.

We display multiple instances of an icon using .

We set the width and height of the icons using CSS. I'm using the same dimensions as the viewBox, but they don't have to be identical. However, to avoid excess empty space inside the SVG, make sure you maintain the aspect ratio.

Icon (width: 100px; height: 125px; )

With this code we got the following result:

Notice that thanks to the added black borders around our SVGs, you can see the borders of each one, including the first one where the content is not rendered. Remember: the SVG document in which you defined symbol will be displayed on the page, but without content. To prevent this, use the display: none property on the first SVG. If you don't hide the SVG with icon definitions, it will appear on the screen even if you don't size it - it will occupy the default 300 by 150 pixels (this is the default value for non-replaced elements in CSS) and you will end up with an empty block on the screen that you don't need .

Now let's try to change the fill color for each icon instance:

Use.ic-1 ( fill: skyblue; ) use.ic-2 ( fill: #FDC646; )

The fill color of the icons still does not change, since the inherited color is overwritten by the fill="#000" attribute in the path element. To prevent this from happening, we need to force path to inherit the color:

Svg path ( fill: inherit; )

Voila! Colors assigned to elements are now applied to the path of each of them. Check out the demo and experiment with the values ​​by creating instances and giving them different colors:

Now this technique works after we forced the content inherit styles. But in many cases this is not exactly what you need. There are other design methods, we will now move on to some of them.

Content design using the CSS all property

Some time ago, while working on an icon activated with , I needed one of the elements inside it to inherit all the styles , such as fill , stroke , stroke-width , opacity and even transform . So I needed to control all of these attributes through CSS, while keeping all the presentational attributes in the markup as a fallback.

If you encounter a similar task, you'll probably think it would take too long to do everything in CSS:

Path#myPath ( fill: inherit; stroke: inherit; stroke-width: inherit; transform: inherit; /* ... */ )

Having looked at this snippet, you will notice a pattern, which means it would make sense to combine all the specified properties into one and set it to inherit .

Fortunately, it will help us CSS property all. My CSS reference book mentions using the all property to style SVG, but it's worth a refresher.

Using the all property we can do this:

Path#myPath ( all: inherit; )

This works fine in all browsers that support all , but be aware of the following: important point: This declaration tells the element to inherit literally all of the properties of its parent, including those you don't want the element to have. So if you don't want all CSS properties to be styled, this won't work for you - it's last resort and it's only partially suitable when you have an unstyled element and full control above its properties in CSS. If you use this declaration and don't define values ​​for all CSS properties, they will cascade until they find a value to inherit, in most cases the browser's default styles.

Note that this only applies to attributes that can be set using CSS, not attributes that can only be set in SVG. If the attribute can be set using CSS, it will inherit styles, otherwise not.

Ability to enable inheritance of presentation attributes for all styles , but what if you have an icon consisting of several elements and you don't want them all to inherit the same fill color? What if you want to apply many different fill colors to different children? Specifying one style in no longer suitable. We need something different to cascade the right colors to the right elements.

Using the CSS currentColor variable to style content

Using the CSS currentColor variable in combination with the technique described above allows you to define two colors for an element rather than just one. Fabrice Weinberg wrote about this a year ago.

The idea is to simultaneously apply to fill and color properties and then cascade those properties to the content , using the capabilities of the currentColor variable. Let's look at some example code to understand how it works.

Let's say we want to design this minimalistic Codrops logo using 2 colors - one for the front drop and one for the back.

First, let's start with the code for this image: we have a symbol containing a description of the icon and three instances , creating three copies of the logo.

If we set the fill color in the element for each instance, this color will be inherited by both blobs, which is not our goal.

So instead of defining a fill color and cascading it in the usual way, we will use the currentColor variable so that the smaller blob in the foreground will be a different color and we will set this value using the color property.

First, we need to insert currentColor where we want to apply this color - this will be the place in the markup where the icon is defined, that is, inside . Now this fragment looks like this:

Next, we need to remove the presentational fill attribute from the second droplet and let it inherit the element's fill color using inherit .

If we were to use the inherit keyword to force presentation attributes to inherit values ​​from , both parts would inherit same value, and currentColor would have no effect. Therefore, in this technique, we need to remove the attribute that we want to set via CSS, and leave only the one in which we will use currentColor .

Now, using the fill and color properties in We will add styles to the drop from the logo:

Codrops-1 ( fill: #4BC0A5; color: #A4DFD1; ) .codrops-2 ( fill: #0099CC; color: #7FCBE5; ) .codrops-3 ( fill: #5F5EC0; color: #AEAFDD; )

Each element gets its own fill and color value. In each, the fill color is cascaded to fill the first path that does not have a fill attribute, and the color property color is used to set the fill attribute in the second path.

So what happened is that the current color value leaked into the element's content styles by using the currentColor variable. Graceful, isn't it?

Here's a demo with the code used:

This two-color technique is great for two-color logos. In his article, Fabrice created three different versions of the Sass logo, changing the color of the text relative to the background.

Keyword currentColor is the only CSS variable available at the moment. However, if we had more variables, could we use them to populate even more values ​​in the content? ? Yes, we could. Amelia Bellamy-Royds introduced the concept for this on her Codepen blog a year ago. Let's see how it works.

The Future: Content Design using CSS variables

The robot code contains all the colors that make up it:

Now, we won't be using CSS variables as fill attribute values ​​for each outline. Instead, we'll use them as fill colors using the CSS fill property, keeping all the fill attributes in place. These attributes will be used as a fallback for browsers that don't support CSS variables - the image will appear as is if the CSS variables don't work.

With the added variables the code will be as follows:

Since inline style tags rewrite presentation attributes, browsers that support CSS variables will use these variables to set the fill color. Browsers that don't support them will use the fill attribute.

Next we need to set the values ​​for the variables in CSS. But first we instantiate the image using :

<xlink:href="#robot" id="robot-1" />

After that, we will set the values ​​of the variables for use so that they can cascade to its contents. The colors you choose will create color scheme drawing. Since our robot uses three primary colors, we will call them primary, secondary and tertiary.

#robot-1 ( --primary-color: #0099CC; --secondary-color: #FFDF34; --tertiary-color: #333; )

You can still use the fill and color properties in conjunction with these variables, but you can get away with it just fine. So, with the colors specified in our variables, the robot looks like this:

You can use as many copies of the image as you like and set each of them to a set of different colors, creating different themes. This is partially useful when you want to design a logo different ways depending on the context and in other similar cases.

As mentioned, browsers that do not support CSS variables use specified presentation attributes as a fallback, while browsers that do support CSS variables use them to populate the fill property and overwrite attributes. But what happens if the browser supports CSS variables, but you forgot to set these variables in styles or set the wrong value?

For our hipster robot, we set three variables and only a few of its fragments do not depend on them - after all, it was originally developed for possible theming. So if you run this code in a browser that supports CSS variables and remove all declarations that declare those variables, you will get the following result:

If variable values ​​are not set or are not correct, the browser will use its default color, which is usually black for fill and stroke in SVG.

A workaround for this is to set a different color as a fallback for supporting browsers. The CSS variable syntax allows you to do this: Instead of passing the variable name as an argument to var(), you pass two arguments separated by a comma - the variable name and a fallback, in this case the value for the presentation attribute.

So now our robot code looks like this:

And it's all. If any variable doesn't have a value set, the browser will always have a color set as a fallback. Amazing.

Using this technique you can display this robot anywhere on the page using , assigning different colors to each instance and resulting in different color themes in the end.

You can experiment with the demo, create as many copies of the robot as you like and color it with any colors - just remember that you must use a browser that supports CSS variables to do this:

If you view this demo in a browser that supports CSS variables, you will see a blue and yellow version of the robot among others, just like we set in the CSS variables. Otherwise, you will see three identical robots with a fallback color.

Summing up

This was a great article.

Using the power of CSS cascade, content styling stored in the shadow DOM becomes less complex. And with CSS variables (currentColor or with custom properties) we can penetrate the shadow DOM and customize our graphics however we want, while creating a fallback in case of problems.

Personally, I really like the combination of CSS and SVG variables. I like their combined functionality, especially in terms of creating a fallback mechanism.

We may also receive other ways to style the content. in the future, as discussions continue about using CSS variables as SVG parameters - so this article does not cover everything there is to learn on this topic.

Working with reusable SVG content is one of the complex issues SVG, this has to do with the behavior and location of the code being cloned. There are a lot of related issues that arise here that could become the topic of separate articles.

Continuation of the previous article “Styling SVG with CSS - Part 1”, dedicated to the format vector graphics SVG.

Styling with CSS

There is a clear and distinct relationship between the HTML and CSS languages: HTML language created for content structuring On the page; task CSS language- external design of this content. SVG format blurs clear boundaries this relationship. For example, format version SVG1.1 does not need CSS for styling individual elements SVG objects - for this purpose there are so-called presentation attributes.

Presentation attributes are shorthand for CSS properties for SVG elements. You can think of these attributes as CSS properties for SVG with a special syntax. Style cascading applies to these properties, but in this article we'll do it in a more concise way.

The example shown below is code that uses presentation attributes to style the border

polygon in the form of a five-pointed star:

In this example the attributes

1 fill
, or , are completely different from their CSS counterparts.

The SVG2 format has several presentation attributes, such as

1 x
,
1 y
,
1 width
,
1 height
,
1 cx
,
1 cy
and some others that cannot be specified using CSS in SVG1.1. A list of new SVG attributes can be found at this link - SVG2 specification.

Another way to style SVG elements is to use CSS properties for this purpose. Just like with HTML elements, CSS properties can be set using an inline style:

"width: 300px; height: 300px;" viewBox = "0 0 300 300" > "fill: #FF931E; stroke: #ED1C24; stroke-width: 5;" points = "279.1,160.8 195.2,193.3 174.4,280.8 117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 " />

SVG Style Cascades

As stated earlier, presentation attributes are a special type of property and that they are simply shorthand for CSS properties that apply to SVG elements. Based on the above, it is logical to assume that the concept of presentational SVG attributes, just like CSS properties, is applicable cascade of styles.

Presentation attributes are positioned as “author style rules” and can be overridden by any other definitions: external style sheets, internal style sheets or inline styles.

The diagram below shows the order of styles in a style cascade. The lower the styles are in this table, the more styles above them they can be overwritten. In our case, presentation styles can be overridden by almost all other styles, except user agent styles:

For example, the code sample below is a circle written in SVG. Circle fill color as an attribute

using the rule , , and .

Notes

Since presentation attributes have XML syntax, they case sensitive. For example, when setting the fill color of an SVG element, the attribute should be written as

V ,
1