I'm unsure of the proper markup to structure, select, and style individual SVG instances called from a common inline SVG "template" within an HTML file.
<!-- first instance to style -->
<svg id="instance1" viewBox="0 0 799.9 177.8">
<use xlink:href="#template">
</svg>
<!-- second instance, want different styles -->
<svg id="instance2" viewBox="0 0 799.9 177.8">
<use xlink:href="#template">
</svg>
In my SVG template, I have a group <g> of several paths, each of which is given a class name. I've given that SVG group an id of template, and am calling instances of it.
<!-- first instance to style -->
<svg id="instance1" viewBox="0 0 799.9 177.8">
<use xlink:href="#template">
</svg>
<!-- second instance, want to apply different styles -->
<svg id="instance2" viewBox="0 0 799.9 177.8">
<use xlink:href="#template">
</svg>
Now I'm attempting to select/style elements these instances in CSS as follows (though this syntax doesn't work!):
/* want to style each instance differently */
#instance1 .outline {
fill: red;
}
#instance2 .outline {
fill: green;
}
I assume this is easy, but I can't figure out the correct way to select/style these individual SVGs that <use> a common set of paths.
Any ideas? Thanks!
Code snippet available for review at http://codepen.io/edhebert/pen/GgmKOo
Contents of <use> are cloned into a shadow DOM and hence cannot be directly selected and styled using CSS the normal straightforward way that we know.
Before going further,note that you can apply styles to the contents of a <use> element by applying the styles to the <use> itself. For example, by doing this:
<svg id="instance1" viewBox="0 0 799.9 177.8">
<use xlink:href="#template" fill="maroon">
</svg>
.. the descendants of <use> will inherit the fill color from the <use> element. But all descendants will inherit this color.
If you want to apply a specific color to only one element inside <use>, for example, another technique can be used. This technique is, however, currently limited.
The technique works by taking advantage of the CSS currentColor variable. Fabrice Weinberg wrote about this technique in this blog post over at Codepen.
Basically, if you have an SVG element that you want to reuse, instead of specifying a fill color inside the "template" on each path, you do this instead:
<g>
<path fill="currentColor" d="..." />
</g>
And then, in your CSS, you can specify the color that you want, knowing that this color will be applied to the above path—because this is how currentColor works.
use#instance1 {
fill: deepPink; /* will be inherited by contents of `use` */
color: #eee; /* will be inherited by the path element */
}
Someone else took this technique further by using user-defined CSS variables to do the exact same thing. You can read about it here. The CSS variables technique is the same as Weinberg's technique, except that you can define as many variables as you want, use them inside your template, and then specify their values in your CSS—these values will then be used by these variables wherever you have defined them inside the template.
This technique works, but CSS variables are currently only supported in Firefox—so I don't suppose you would use it in production.
Hope this helps.
Related
I have a svg with different paths, ellipses etc. They have different fill colours. Say red & blue. Now, I put them all into a sprite, and would now like to modify fill colour with css on hover, so what I would normally do is remove the fills from the svg and do everything with css' fill property.
However, since I have different colours here, I cannot simply do fill:red, since everything will be red, but I want some of it to be blue.
You can add a different class to each of the paths:
<circle class="circleClass" cx="40" cy="50" r="26"/>
<square class="squareClass" cx="40" cy="50" r="26"/>
Then target those classes in your CSS:
.circleClass {
fill: red;
}
You can add a class to every path or you can use the nth-child.
Here is an easy example:
<path bla-bla-bla>
<path bla-bla-bla>
<path bla-bla-bla>
path:nth-child(1){
fill:red;
}
path:nth-child(2){
fill:blue;
}
path:nth-child(3){
fill:green;
}
What you are doing can't work. Anything referenced via a <use> is not present in the DOM under the <use> element.
.icon:hover .outer { }
won't work because the path with class outer is not a descendant of .icon. If you want to style the contents of a symbol, you need to do it by applying the ruules directly to the symbol. For example:
#btn-tester .outer { }
Unfortunately :hover events don't apply to symbols. So you can't do:
#btn-tester:hover .outer { }
Even if that worked, you may not want to do that anyway. If there were any other uses of the symbol on the page, it would change them also.
You probably are going to have to just inline the SVG on the page where you want it. Instead of using a symbol.
I created a svg chart, I added a tooltip that shows the corresponding value when the mouse hovers.
The problem is, since the path is rendered after the bars are created, then the tooltip is show behind the path http://take.ms/lljq3. what I need is that the tooltip is always in front of everything.
I try to add z-index:-1; position: relative; to the path and z-index:999; position: fixed; to the text but is not working.
See the example here: https://jsfiddle.net/sgcw8btx/
When creating svg elements, following rule applys:
3.3 Rendering Order
Elements in an SVG document fragment have an implicit drawing order, with the first elements in the SVG document fragment getting "painted" first. Subsequent elements are painted on top of previously painted elements.
Isn't it possible to place the tooltip element before the bar / line?
Otherwise you could try using use?
<use xlink:href="#id" />
And you could try to embed the HTML directly:
<svg xmlns="http://www.w3.org/2000/svg">
<g transform="translate(20,30)">
<rect width="200" height="150"/>
<foreignObject width="200" height="150">
<body xmlns="http://www.w3.org/1999/xhtml">
<div>
Hello, <b>World</b>!
</div>
</body>
</foreignObject>
</g>
</svg>
This question already has answers here:
How do I select an element based on the state of another element in the page with CSS?
(3 answers)
Closed 6 years ago.
So I have a HTML structure like this:
<g>
<text></text>
</g>
<g>
<g>
<path></path>
</g>
<g>
<text></text>
</g>
</g>
And I want to change the text elements css after a psudeo :hover from path, can I target this somehow with SCSS? Here is what I have so are:
g{
path{
&:hover {
&& + g{
text{
opacity: 1.0 !important;
filter: alpha(opacity=100) !important;
So I just want to grab the side by g tag from the path tags css, is this possible?
In CSS you are not able to address a parent from a specific action on a child element ... as SASS only generates CSS it's then impossible too.
A solution could be to put a text element in each path elements (or g elements containing path) and then, to write :
HTML :
<g>
<g>
<path>
<text></text>
</path>
</g>
</g>
SCSS :
g {
g:hover > path > text {
color: #FFF;
}
}
If you don't want to modify HTML structure, and want to modify the style of a parent element from the hover pseudo selector of a child, you should use Javascript or a Javascript framework/library (like jQuery, Angular, React, ...).
I have a SVG sprite which contains many icons, but to keep it simple let's say it looks like the following:
<svg>
<symbol viewBox="0 0 612 612" id="icon-foo">
<path class="a" d="..."/>
<path class="b" d=..."/>
<path class="c" d="..."/>
</symbol>
</svg>
This SVG sprite is added to the bottom of page using XMLHttpRequest.
To display icons on the page I am using the following:
<svg id="bar">
<use xlink:href='#icon-foo'></use>
</svg>
and everything is working fine, I see the icons on the page.
The problem:
As you can see in the sprite I have 3 path elements with different classes on the symbol element with the id icon-foo, and in the page where I display icon the id of svg element is bar.
I want to be able to style each path separately using css, but the only way that worked to me is to style them like this:
#icon-foo .a {}
#icon-foo .b {}
#icon-foo .c {}
and this is not very useful especially if I want to display a icon twice on the same page with different colours / options.
Ideally I thought that something like this could work:
#bar .a {}
#bar .b {}
#bar .c {}
but it is not working because obviously we don't have child elements .a, .b, .c in our #bar element.
My question:
Is it possible when displaying icons using xlink:href to style paths separately and if I want to display the same icon multiple times on a page to be able to style their paths separately? If it's possible, then how?
I am fairly new to SVG but how can I display a SVG icon and change its color using inline CSS? For example, if I wanted to change the color of example.svg to #FFF000 how would I do that?
I tried searching online but I couldn't find anything.
collinksmith did answer your question but didn't explain that you cannot change the colour of a .svg file with CSS. You need to add the SVG inline then you can apply CSS to it.
You need to use the fill property of the svg's path. Assuming an svg html element, with a class set on the svg element itself:
.class-name path {
fill: red;
}
EDIT Here's an example: https://jsfiddle.net/4447zb7o/
EDIT 2 To set the css inline, change the style attribute of the path element inside the svg:
<svg class="my-svg" height="210" width="400">
<path style="fill: green" d="M150 0 L75 200 L225 200 Z" />
</svg>