I have a white image that I am using as a background for a div, and I would like to colour to match the themes main colour. I am aware I can do:
filter: sepia() saturate(10000%) hue-rotate(30deg);
and cycle through hue-rotate
to find a colour, but is it possible to calculate this value in advance? Given that the specified hex value is quite dark, I imagine I will need to include the invert(%)
filter as well.
Given a hex value of #689d94
what math do I need to do to calculate the desired hue-rotate
and invert
value to convert my white background image into the same colour?
Here's a snippet of a div
with a white background image being filtered green. The trick here, is it is the whole of the div
that is being filtered, not just the image. If I was to enter some text into the div
the text colour would turn green as well.
div {
background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat scroll 0 0 transparent;
background-size:5em;
width:5em;
height:5em;
-webkit-filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg);
filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg);
}
<div></div>
<p style="background: #689d94"></p>
For RGB color #689d94
, which is rgb(104, 157, 148)
, divide each primary color's value by 255:
Put these weights into the SVG <filter>
matrix (5ᵗʰ column in the first 3 rows):
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="689d94" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix"
values="0 0 0 0 0.40784
0 0 0 0 0.61569
0 0 0 0 0.58039
0 0 0 1 0"/>
</filter>
</defs>
</svg>
The <filter>
has to have id (I used the RGB hex code 689d94
), so we can use it as a reference.
Since some browsers (e.g. Firefox) don't see/use the SVG filter if the display
property of the SVG element is set to none
, and having this SVG element in HTML code would inconveniently occupy some space, the best way is to convert this SVG into a pure inline CSS filter.
To get an inline filter value, take the above listed SVG code, transform it into a single line by remove line breaks and unnecessary spaces, then prepend url('data:image/svg+xml,
and append the previously mentioned id as #689d94')
:
div {
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="71.063" height="60.938"><path d="M33.938 0l-16.97 19.906H1.625L0 21.781v8.781l1.25 1.407h4.781l5.875 28.969h46.969l6.188-28.97h4.687l1.313-1.343v-8.844L69.5 19.906H54.656L37.312 0h-3.375zm1.593 7.594l9.594 12.312H26.25l9.281-12.312zm-20.281 16s-.405 2.9 1.594 3.844c1.998.942 4.406.03 4.406.03-1.666 2.763-3.638 3.551-5.469 2.688-3.312-1.562-.531-6.562-.531-6.562zm41.188.031s2.749 4.969-.563 6.531c-2.487 1.162-4.848-1.541-5.438-2.656 0 0 2.377.88 4.375-.063 1.999-.942 1.625-3.812 1.625-3.812z"/></svg>') no-repeat; // optimized from http://richard.parnaby-king.co.uk/basket.svg
background-size: 100%;
display: inline-block;
height: 5em;
width: 5em;
}
#colored {
filter: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><defs><filter id="689d94" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="0 0 0 0 0.40784 0 0 0 0 0.61569 0 0 0 0 0.58039 0 0 0 1 0"/></filter></defs></svg>#689d94');
margin-left: 20px;
}
<!-- No <svg> in HTML; pure CSS -->
<div></div><div id="colored"></div>
<p style="background: #689d94"></p>