CSS: Change SVG Backgrounds. Styling SVG with CSS. Features and Limitations
This page shows how to use CSS with a special language for creating graphics: SVG.
You'll make a small example that can be run in any browser that supports SVG.
General information: SVG
SVG(Scalable Vector Graphics) is a subset of the XML language and is designed for creating graphics.
SVG can be used for static images, as well as for animations and creating user interfaces.
Like other XML-based languages, SVG supports the use of CSS style sheets, which allows you to decouple different visual options from the data structure.
Additionally, style sheets that you use in other document markup languages may contain a reference to SVG graphics in places where an image is needed. For example, in the style sheet for your HTML document, you can specify a link (URL) to an SVG graphic in the background property.
At the time of writing (mid-2011), most modern browsers have basic SVG support, including Internet Explorer 9 and higher. Some advanced SVG features are not supported, or are only partially supported, in certain browsers. For more information on current SVG support, see SVG tables on caniuse.com, or see the SVG element reference compatibility tables for information on individual element support. In other versions, you can add SVG support by installing an additional plugin, for example, provided by Adobe. For more information about SVG in Mozilla, see the SVG page on this wiki. |
Get to Work: SVG Demo
Create a new SVG document as a regular text file, doc8.svg. Copy and paste the contents of the block below, making sure to scroll all the way through to copy everything:
Create a new CSS file, style8.css. Copy and paste the contents of the block below, making sure to scroll all the way through to copy everything:
/*** SVG demonstration ***/ /* page */ svg ( background-color: beige; ) #heading ( font-size: 24px; font-weight: bold; ) #caption ( font-size: 12px; ) /* flower */ #flower:hover ( cursor: crosshair; ) /* gradient */ #fade-stop-1 ( stop-color: blue; ) #fade-stop-2 ( stop-color: white; ) /* outer petals */ #outer-petals ( opacity: .75; ) #outer-petals .segment-fill ( fill: azure; stroke: lightsteelblue; stroke-width: 1; ) #outer-petals .segment-edge ( fill: none; stroke: deepskyblue; stroke-width: 3; ) #outer-petals .segment:hover > .segment-fill ( fill: plum; stroke: none; ) #outer-petals .segment:hover > .segment-edge ( stroke: slateblue; ) /* inner petals */ #inner-petals .segment-fill ( fill: yellow; stroke: yellowgreen; stroke-width: 1; ) #inner-petals .segment-edge ( fill: none; stroke: yellowgreen; stroke-width: 9; ) #inner-petals .segment:hover > .segment-fill ( fill: darkseagreen; stroke: none; ) #inner-petals .segment:hover > .segment-edge ( stroke: green; )
Open the document in your SVG-enabled browser. Move your mouse pointer over the image.
This wiki does not support inserting SVG into pages, so we are not able to demonstrate it here. The image will look like this:
What's next?
In this demo, your SVG-enabled browser already knows how to render SVG elements. The style sheet just changes the display in some way. The same thing happens with HTML and XUL documents. However, CSS can be used for any XML document that does not have a default way to render elements. This example is shown on the following page:
CSS is becoming more powerful every day, with many new features emerging that make it much easier to create user interfaces. And that is great!
One such feature in CSS is filters. Let's try using filters to work with SVG images.
CSS filters
First, let's take a look at filters. They include the following features:
- blur()
- brightness()
- contrast()
- drop-shadow()
- grayscale()
- hue-rotate()
- invert()
- opacity()
- saturate()
- sepia()
CSS filters are the easiest way to implement basic transformations in a browser-efficient manner.
If you want to see how each filter works, we recommend visiting the website: cssfilters.co.
Editing SVG backgrounds
I love using SVG (scalable vector graphics) format on the web. SVG is a great image format for the web. When you add an SVG to a page, you have access to every element and property within it. This allows you to add animation, change colors, and dynamically add information. SVG is also great for icons.
SVG is often used as background images. In this case, you lose control over the elements of the image. You now cannot change colors or properties, since the SVG becomes a regular image. But with the help of CSS filters you can solve this problem.
Brightness adjustment
The first thing I encountered when working with icons was the need to darken a white icon on a light background. To avoid creating a new dark icon, I used filter: brightness().
A brightness value greater than 1 makes the element brighter, less than 1 makes the element darker.
Icons with color #000 or rbg(0, 0, 0) will not be clarified. They must be any other color.
Color adjustment
We looked at how to change the brightness of the icon. But what if we want to change the color of the icon? In this case, a filter will help us sepia, hue-rotate, brightness And saturation to create any color we want.
From white you can create, for example, blue, cyan and pink.
Colorize-pink ( filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5); .colorize-navy ( filter: brightness(0.2) sepia(1) hue-rotate(180deg) saturate( 5); ) .colorize-blue ( filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6); )
Compatibility
At the time of writing, filters are supported by the following browsers:
Instead of a conclusion
Never forget about your users. So far, filters do not work everywhere. Therefore, do not use white filter icons on a white background, as some users simply will not see anything. Also, don’t forget about alternative text for images.
Original article: link Author of the article: Alex. Category:
Date of publication: 04/01/2018
SVG is the new standard for vector images in the browser. Vector editors such as Adobe Illustrator allow you to directly save the file in 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 that you use 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 define the appearance of multiple elements in an 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 the SVG display 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 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.
Detailed article on styling content in an SVG element
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
But before we begin, let's quickly look at the basic structure and grouping of elements in SVG, gradually moving on to
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:
Element
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
Element
At the element
Element
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
But what is the content?
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
An icon is displayed on the screen, the contents of which are defined internally
But the element
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
So the contents
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 (this feature is not available in Firefox at the moment). 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
Using the Chrome Developer Tools, you can inspect the contents of the use element inside the shadow DOM (“#shadow-root”, the line grayed out). 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
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
We know that we can't set styles internally
But we also know that, as with the element
So, first let's try to change the fill color of the element inside
However, this raises a couple of questions:
- 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). - If you exported the SVG from a graphics editor or are otherwise unable to modify the SVG code, then you will end up working with an SVG that already has presentation attributes applied (unless you explicitly disable this when exporting to SVG format) and the values of these attributes will take precedence over those 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:
- 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).
- By resetting values, you force yourself to style the entire set of properties.
- Presentation attributes, which are initially set, are a great 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
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 the following example - an ice cream icon drawn with a single 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
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 white space within 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
Now this technique works after we forced the content
Content design using the CSS all property
Some time ago, while working on an icon activated with
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 .
Luckily, the CSS all property can help us. 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 there's one important thing to consider: 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 unless you want all CSS properties to be styled, this won't work for you - it's a last resort and is only partially suitable when you have an unstyled element and full control over its properties in the 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
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
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
If we set the fill color in the element
So instead of defining the fill color and cascading it in the usual way, we'll use the currentColor variable so that the smaller blob in the foreground will be a different color and we'll set that 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
Next, we need to remove the presentational fill attribute from the second droplet and let it inherit the element's fill color
If we were to use the inherit keyword to force presentation attributes to inherit values from
Now, using the fill and color properties in
Codrops-1 ( fill: #4BC0A5; color: #A4DFD1; ) .codrops-2 ( fill: #0099CC; color: #7FCBE5; ) .codrops-3 ( fill: #5F5EC0; color: #AEAFDD; )
Each element
So what happened is that the current color value leaked into the element's content styles
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.
The currentColor keyword 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?
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:
Because inline style tags override 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
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 the color scheme of the 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 style the logo in different ways depending on the context and other similar cases.
As mentioned, browsers that don't support CSS variables use the given presentation attributes as a fallback, and 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
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
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.
Working with reusable SVG content is one of the tricky parts of SVG, it has to do with the behavior and placement of the code being cloned. There are a lot of related issues that arise here that could become the topic of separate articles.