Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

currentColor inheritance for SVG url

Tags:

css

svg

Same question as How do I have an SVG image inherit colors from the HTML document?, but specifically when applied to an svg image used as content on a :before pseudo-element.

(Desired behavior is that both checkmarks inherit the red color from the body. Currently only the inline SVG does.)

<style type='text/css'>
    body {
        color: red;
    }

    .checkmark {
        height: 2em;
        width: 2em;
    }

    .checkmark:before {
        content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='-0.5 0 20 15'><rect fill='currentColor' stroke='none' transform='rotate(45 4.0033 8.87436)' height='5' width='6.32304' y='6.37436' x='0.84178'></rect><rect fill='currentColor' stroke='none' transform='rotate(45 11.1776 7.7066)' width='5' height='16.79756' y='-0.69218' x='8.67764'></rect></svg>");
    }
</style>

<!-- Renders red -->
<svg xmlns='http://www.w3.org/2000/svg' width='2em' height='2em' viewBox='-0.5 0 20 15'><rect fill='currentColor' stroke='none' transform='rotate(45 4.0033 8.87436)' height='5' width='6.32304' y='6.37436' x='0.84178'></rect><rect fill='currentColor' stroke='none' transform='rotate(45 11.1776 7.7066)' width='5' height='16.79756' y='-0.69218' x='8.67764'></rect></svg>

<!-- Renders #000 -->
<div class="checkmark"></div>

jsFiddle Demo

like image 381
Adam Avatar asked Dec 11 '13 02:12

Adam


People also ask

Can SVG use currentColor?

This is where the currentColor property shines. We can use it for our fill value, and the SVG will pick up whatever the current color of the link is.

How add SVG to HTML?

SVG images can be written directly into the HTML document using the <svg> </svg> tag. To do this, open the SVG image in VS code or your preferred IDE, copy the code, and paste it inside the <body> element in your HTML document. If you did everything correctly, your webpage should look exactly like the demo below.

How does SVG define color?

In an SVG file, they can be specified both in the style attribute ( fill and stroke properties) and using fill and stroke attributes as presentation attributes. So you can set color for SVG elements in two ways: using fill and stroke properties of the style attribute and using fill and stroke attributes.


2 Answers

content: url(...) makes the url part into an image, in other words the svg becomes its own separate document. Styles don't apply across documents, so it's not possible to get color to affect the svg in this scenario.

When the svg is inline it is OTOH part of the document, so styles can be applied to it.

You could make (or dynamically generate) multiple versions of the checkmark svg and tune the stylerules such that the appropriate "pre-colored" one is selected.

like image 88
Erik Dahlström Avatar answered Sep 30 '22 13:09

Erik Dahlström


For certain usecases where the icon is all the same color, you can get away with using a css filter on the element instead of changing it's color.

E.g. don't use currentColor in your SVG url, but instead use a base color e.g. red Then instead of changing the color on the containing element (your containing element is <body> for illustration purposes, but I'm thinking of an <a href="#" class="checkmark"> here), add a filter to the element:

.checkmark {
    color: red;  /* matches fill in the SVG */
}

.checkmark::before {
    content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='-0.5 0 20 15'><rect fill='red' stroke='none' transform='rotate(45 4.0033 8.87436)' height='5' width='6.32304' y='6.37436' x='0.84178'></rect><rect fill='red' stroke='none' transform='rotate(45 11.1776 7.7066)' width='5' height='16.79756' y='-0.69218' x='8.67764'></rect></svg>");
}

.checkmark::before:hover {
    filter: hue-rotate(120deg);  /* changes both text and tick from red to green */
}

You'll have to play around with the filter to get the right color transformation, e.g. you can also change brightness or make it grayscale: https://css-tricks.com/almanac/properties/f/filter/

like image 23
EoghanM Avatar answered Sep 30 '22 13:09

EoghanM