Clear an already set "fill" property in CSS to get defaults back for an SVG - css

I'm using a platform that within it's own CSS it sets the fill property as so:
.tatsu-svg-icon-custom svg * {
fill: currentColor;
}
This ends up with an SVG I am adding being black in this instance - which is not helpful. This particular SVG is a multi-colored SVG and handles all the fill properties itself within the code of the SVG.
Obviously if I change this property to aother color, it colors the whole SVG that color - so that is not helpful either.
So my question is, how do I get the defaults back so it doesn't apply any color to it? Setting it to initial makes the SVG transparent.

The keyword that would help in this situation is revert-layer. Unfortunately, it is currently only implemented in Firefox (>= 97).
(This example will seem to work even for other browsers. But that is because for them, it is an invalid keyword.)
.tatsu-svg-icon-custom svg * {
fill: revert-layer;
}
<div class="tatsu-svg-icon-custom">
<svg width="100" viewBox="0 0 20 20">
<circle r="5" cx="5" cy="5" fill="yellow" />
<circle r="5" cx="5" cy="15" fill="blue" />
<circle r="5" cx="15" cy="5" fill="red" />
<circle r="5" cx="15" cy="15" fill="green" />
</svg>
</div>

Related

SVG radius or position with CSS variables

Is it possible to use CSS Variables in SVG to manipulate values like radius or position in the "attribute styles" of an element?
For Example, in the below code, I have added a CSS color variable - --dark-text-clr and a radius variable --radius. When I use the color CSS variable in fill it renders fine - 1st circle, but using the radius variable doesn't render the element - 2nd circle.
:root{
--dark-text-clr: blue;
--radius: 12;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
<circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
<circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
Yes, but CSS must have units for non-zero values.
:root{
--dark-text-clr: blue;
--radius: 12px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
<circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
<circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
According to the MDN Docs "Starting with SVG2, r is a Geometry Property meaning this attribute can also be used as a CSS property for circles."
There are three ways to set the radius value
as attribute
<circle ... r=10>
via class and stylesheet
circle {
r: 10px;
}
inline in 'style' attribute
<circle... style="r: 10px;" ></circle>
The last way has the greates presedence. Take a look at this example where all circle elements have r set as attribute, which is overridden by the stylesheet (2nd circle), which is overridden again by the inline style attribute (3rd circle)
(These three ways don't have to be used together, but are only combined to demontrate which one has a higher presedence and overwrites the already set values)
:root {
--dark-text-clr: purple;
--radius: 20px;
}
.circle {
r: 10px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="300px" viewBox="0 0 300 300">
<circle cx="10" cy="10" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5></circle>
<circle cx="30" cy="30" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle"></circle>
<circle cx="60" cy="60" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle" style="r: var(--radius);" ></circle>
</svg>
Setting r with the variable on the attribute seems to be working in firefox, but not in chrome/edge
<circle ... r="var(--radius);" ></circle>
so better set it on the style attribute
<circle ... style="r: var(--radius);" ></circle>

Colorize transparent part of SVG icons

I want to colorize a transparent part of a svg icon from font awesome. I am using Vue Fort-Awesome package.
Here as you see inner part of icon is getting the background image of my main div. However I don't want those part to be transparent. Do you have any tricky solution for it? I know this question can be very easy but I couldn't find how to search for it on google.
<v-icon
icon="minus-circle"
class="w-6 h-6 rounded-full text-red-500"
/>
Those are technologies that I use but simple css trick can be acceptable too.
Tailwind
Vue3
FortAwesome
You can change the color of the minus or circle by changing the hex value in the fill section.
For other icons, you can change color by editing the svg file.
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="100" fill="#00970F"/>
<rect x="39" y="88" width="123" height="25" rx="10" fill="#FA00FF"/>
</svg>

Reuse set of many objects but now assign each object a separate opacity, without copying all code?

Let's imagine we have a large set of many objects, say rectangles. They all have opacity 1.
Now imagine that we want to copy all of those objects again to create a new set, but this time each object would need to be assigned a separate opacity.
One can create many such sets, and each time all of the individual objects would separately be assigned a certain opacity.
In cross-browser compatible SVG1.1 (optionally with SMIL/CSS), is there a way to do this, without needing to redraw all of the shapes and their alignments all over again (redrawing would make the code sort of long), for example using set?
The pattern you are looking for goes like this:
<svg width="300" height="150"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="template" x="20" y="20" width="80" height="80" />
<use xlink:href="#template" x="100" style="opacity:0.6" fill="blue" />
<use xlink:href="#template" x="200" style="opacity:0.3" fill="green" />
</svg>
The <use> elements reuse the template element. The <rect> is now in the so-called "shadow DOM" below that use element. While it is treated as if it was a child, it cannot be targeted by CSS style rules. But it can inherit styles (or presentation attributes) from the parent <use> element.
Note that the template element does not set an opacity. As a default, it is rendered with opacity="1". Now if the <use> element sets another opacity, it can be applied to the cloned <rect> by inheritance.
If the template had an explicit opacity="1", the cloned <rect> would also get that. That style would have a higher specificity than the inherited one, and the rectangle would stay fully opaque.
Building on this answer, if you want to clone sets of elements at once but give each of them individual opacity values, CSS variables can be leveraged. Note that presentation attributes no longer work. The most concise way to write this is a stylesheet that turns out to be a list of the property values to use.
.stand {
--red: 1;
--amber: 0.3;
--green: 0.3;
}
.wait {
--red: 1;
--amber: 1;
--green: 0.3;
}
.go {
--red: 0.3;
--amber: 0.3;
--green: 1;
}
.stop {
--red: 0.3;
--amber: 1;
--green: 0.3;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200">
<symbol id="trafficlight">
<rect x="20" y="20" width="60" height="160" />
<circle cx="50" cy="50" r="20" fill="#d00" style="opacity:var(--red, 1)" />
<circle cx="50" cy="100" r="20" fill="#fa0" style="opacity:var(--amber, 1)" />
<circle cx="50" cy="150" r="20" fill="#0b0" style="opacity:var(--green, 1)" />
</symbol>
<use x="0" xlink:href="#trafficlight" class="stand" />
<use x="100" xlink:href="#trafficlight" class="wait" />
<use x="200" xlink:href="#trafficlight" class="go" />
<use x="300" xlink:href="#trafficlight" class="stop" />
</svg>

Add css to svg with inkscape

I use Inkscape for creating svg images and want to know how to use not embedded css rules.
For example
draw rectangle
in XML-editor add class attribute as
class="rect1"
to svg:rect object
How to add css like
.rect1 {
fill:#ffef00;
}
Here's an example of an SVG in an HTML page that you can style with CSS:
HTML page
<div id="mySvg">
<svg>
<use xlink:href="images/logo.svg#shape" />
</svg>
</div>
The SVG (located at images/logo.svg)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="shape">
<rect x="50" y="50" width="50" height="50" />
<circle cx="50" cy="50" r="50" />
</g>
</defs>
</svg>
The CSS
svg {
fill: currentColor;
}
#mySvg {
color: green;
}
See working example: plunker
Notes
If you use Inkscape to create your SVG, you'll probably have to do some hand-editing of the SVG to make it styleable with CSS.
Make sure the SVG code doesn't have any fill attributes in it (fill should be in the CSS). When making an SVG with Inkscape, it often has a fill:none or something. You'll have to manually remove those.
When using Inkscape, save files as "Optimized SVG" as described here.

Is it possible to use a background image on the stroke of an SVG element?

Just as the question asks - I'm trying to figure out whether or not it's possible to use some kind of pattern or repeated background image for the stroke of an SVG path.
Is this doable? Or are you limited to colors only?
TIA!
You can use a <pattern> as a stroke e.g.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="p1" patternUnits="userSpaceOnUse" width="32" height="32">
<image xlink:href="http://phrogz.net/tmp/alphaball-small.png" width="32" height="32" />
</pattern>
</defs>
<rect stroke-width="32" stroke="url(#p1)" width="200" height="200" fill="none"/>
</svg>
The pattern can contain <svg> drawing elements or (as here) an image, or both.
You can use the property stroke-dasharray for "patterns" in the stroke:
<line stroke-dasharray="5, 5" x1="10" y1="10" x2="190" y2="10" />
With this you can specify the length of strokes and gaps between. For some examples have a look at the MDN example page.

Resources