OpenLayers Icon className SVG - Change Fill Via CSS? - css

I'm trying to use CSS classes in openlayers to change an svg fill colour:
eg say in open layers I have
style = new Style({
image: new Icon({
src: styleConfig.image.src,
scale: styleConfig.image.scale,
offset: [styleConfig.offsetX, styleConfig.offsetY],
className: 'icon--blue'
}),
zIndex: styleConfig.zIndex
});
and then I have an SVG like so:
<svg xmlns="http://www.w3.org/2000/svg" width="49" height="44" viewBox="0 0 580 515" class="icon--blue"><circle fill="inherit" cx="475" cy="106.9" r="102.9"/><g class="cat"><circle fill="inherit" cx="475" cy="106.9" r="102.9"/></g></svg>
and some CSS like so:
.icon--blue circle {
fill: #0000ff !important;
}
.icon--blue .cat {
display: none;
}
Try as I might I cannot get the css based fill effect to be applied. I was wondering if this is supported?
Also the hiding of the grouping with the class name of "cat" also doesn't work.
Seeing is OpenLayers is rendering to canvas, debugging this kind of stuff is very difficult.

Start with a Proof of Concept SVG in a JSFiddle or CodePen, to get your SVG and CSS selectors right.
Learn CSS Specificity to understand why the .inner circle below is green and not red;
Most likely no need for fill attribute and hardly ever !important
<style>
svg {
width: 25%;
}
circle {
fill: green;
stroke: red;
}
#outer {
fill: blue;
}
.inner {
fill: red;
}
.hidden {
display: none;
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<circle id="outer" cx="10" cy="10" r="8" />
<g class="inner">
<circle cx="10" cy="10" r="4" />
</g>
<circle class="hidden" cx="15" cy="15" r="4" />
</svg>

Related

Change svg color on button click via typescript

I want to change the fill color of my SVG when I do a button click. I am able to change it via external CSS(using npm package angular-svg-icon) but I don't know how to do this via typescript. I've encountered a similar question here in stackoverflow but no one has given an answer to the user: svg change rectangle Color on button ng-click
circle.svg:
<svg id="bars" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 63.15 224.35">
<circle class="cls-1" cx="50" cy="50" r="50" fill="#529fca" />
</svg>
tab1.page.html:
<ion-content>
<svg-icon [applyCss]="true" src="assets/images/circle.svg" [svgStyle]="{ 'height.px':200, 'width.px':200 }" />
<ion-button (click)="ChangeColor()">Click</ion-button>
</ion-content>
tab1.page.scss:
#bars{
position: absolute;
top: 80px;
right: 80px;
width: 200px;
height: 100px;
}
.cls-1 {
fill:blue;
}
function where I plan to manipulate the SVG color: ChangeColor(){ }
You can add conditional class on your svg and apply css for fill something like
<circle [ngClass]="{'someclassname': yourconditionvariable}"></circle>
in css
.someclassname{
//your css to fill the color
}
then in changecolor method set yourconditionvariable to true
StackBlitz

SVG fill with css variables

I am trying to use CSS variables in my SVG (which is set as a background image) for the fill color, but am having difficulty in getting it to work. It shows the default black, but when I inspect it I can see that the css variable is there and showing my desired color.
HTML
<div class="test">
Testing the css variable color
</div>
<div class="icon">
</div>
CSS
:root {
--primary-color: hsl(332, 61%, 78%);
}
div {
width: 100px;
height: 100px;
}
.test {
background: var(--primary-color);
}
.icon {
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129'%3E%3Cpath d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='var(--primary-color)' /%3E%3C/svg%3E");
}
Here is a codepen to check out!
I've seen CSS Variables being used in SVG here but I'm not sure if it's possible to do with background images? I'm new to both using SVG and CSS variables so I'm not sure if I'm doing something wrong... Would love some insight as to why it's not rendering the color properly!
Now you can include SVG as mask-image instead of background. Don't forget set background color from css variables for .icon block.
.icon {
background: var(--primary-color);
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129'%3E%3Cpath d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' /%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129'%3E%3Cpath d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' /%3E%3C/svg%3E");
}
You can check it in this CodePan
Here is information from Caniuse about mask-image
And here documentation about mask property
Okay here we go... I will first explain why it does not work and then I will show an alternative.
Why your approach doesn't work
In your example the svg is not part of the DOM. So you cannot use css to modify the attributes of the svg.
What you are doing is adding an inline-style to the svg in your url. Since the browser does not recognise --primary-color as a color it doesn't work.
An alternative approach
An alternative approach is to put the svg in the html and fake a background. I did this by absolute positioning the svg and moving it to the background with z-index.
Do note you will have to modify the svg or the positioning to place the background in the way you want. Normally you would use background-size for this. But with some effort you can replicate this behaviour within the svg or position it better by using css.
:root {
--primary-color: hsl(332, 61%, 78%);
}
div {
width: 100px;
height: 100px;
}
.test {
background: var(--primary-color);
}
.icon{ /*postion relative for absolute positioning to work*/
position: relative;
}
.icon>svg{
position: absolute;
top: 0px;
right: 0px;
left: 0px;
bottom: 0px;
z-index: -1;
}
.icon>svg>path{ /*target the image with css*/
fill: var(--primary-color);
}
<div class="test">
Testing the css variable color
</div>
<div class="icon">
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129' id='background'><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z'/> </svg>
<p>Text goes here...</p>
</div>
Don't include svg as background, by doing that you don't have control over it's fill, instead try adding it inline in html and via css you can control the fill via css variable, please check the working example below, hope it helps :)
:root {
--primary-color: hsl(332, 61%, 78%);
}
div {
width: 100px;
height: 100px;
}
.test {
background: var(--primary-color);
}
.icon {
color: var(--primary-color);
fill: currentColor;
width: 64px;
height: 64px;
}
<div class="test">
Testing the css variable color
</div>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129 129">
<path d="m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z"/>
</svg>
Using the <symbol> tag and CSS variables
CSS variables inherit the fill property. Therefore, it is possible to assign (declare) a variable inside the <symbol> tag, the value of which can be subsequently changed many times for each instance of the svg element.
<symbol id="monstr">
<rect width="100%" height="100%" fill="transparent" />
<path id="face" fill="var(--color-face)" d="M15.4,34.1L24,37l8.6-2.9c1.9-0.6,3-2.6,2.6-4.6L33,20H15l-2.2,9.5C12.3,31.5,13.5,33.5,15.4,34.1z"/>
<path id="nose" fill="var(--color-nose)" d="M29,30l-3-3h-4l-3,3v7c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V30z"/>
Each path, circle, ellips, etc. can be assigned its own variable fill = "var (- color-face)" for fill and then change its value in the external style sheet:
.monstr-colors { --color-face: #7986CB; --color-nose: #9FA8DA; }
This technique creates powerful and flexible styling options for multicolor svg.
For example, for one state of an icon, we can assign one color scheme, and with : hover, assign a different color set to the same icon.
.monstr-colors {
--color-face: #7986CB;
--color-nose: #9FA8DA;
}
.monstr-colors:hover {
--color-face: #3F8B4D;
--color-nose: #58C46C;
)
Below is an example, according to your taste, the color scheme of the image is easily created and changed:
.monstr-colors {
--color-face: #7986CB;
--color-nose: #9FA8DA;
--color-hair-right:#3949AB;
--color-hair-right2:#3949AB;
--color-hair-left:#3949AB;
--color-hair-left2:#3949AB;
--color-eye-right:#1A237E;
--color-pupil-right:#77006B;
--color-eye-left:#1A237E;
--color-pupil-left:#77006B;
--color-ellipse1:#9FA8DA;
--color-ellipse2:#7986CB;
--color-ellipse3:#C5CAE9;
}
.monstr-colors:hover {
--color-face: #3F8B4D;
--color-nose: #58C46C;
--color-hair-right:gold;
--color-hair-right2:#FFBB00;
--color-hair-left:gold;
--color-hair-left2:#FFBB00;
--color-eye-right:#77006B;
--color-pupil-right:#FF4151;
--color-eye-left:#77006B;
--color-pupil-left:#FF4151;
--color-ellipse1:#FFDD00;
--color-ellipse2:#C1A700;
--color-ellipse3:#FFEE7D;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="192" height="192" viewBox="0 0 48 48" >
<symbol id="monstr">
<rect width="100%" height="100%" fill="transparent" />
<path id="face" fill="var(--color-face)" d="M15.4,34.1L24,37l8.6-2.9c1.9-0.6,3-2.6,2.6-4.6L33,20H15l-2.2,9.5C12.3,31.5,13.5,33.5,15.4,34.1z"/>
<path id="nose" fill="var(--color-nose)" d="M29,30l-3-3h-4l-3,3v7c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V30z"/>
<path id="hair-right" fill="var(--color-hair-right)" d="M31,7c-0.5,0-1,0.4-1,1c0,0,0,0,0,0c-0.4,0-0.8,0.2-0.9,0.6c-0.2,0.5,0,1.1,0.6,1.3 C30,10.1,40,14.4,40,32.4V37c0,0.6,0.4,1,1,1s1-0.4,1-1v-4.6c0-14.4-6.1-20.7-9.5-23.1C35.9,10.3,44,14.7,44,34c0,0.6,0.4,1,1,1 s1-0.4,1-1C46,7.7,31.6,7,31,7z"/>
<path id="hair-right2" fill="var(--color-hair-right2)" d="M29.5,10.1c-0.5-0.3-1.1-0.1-1.3,0.4c-0.3,0.5-0.1,1.1,0.4,1.4c0.1,0,7.5,4.3,7.5,20.1v8c0,0.6,0.4,1,1,1 s1-0.4,1-1v-8C38,14.9,29.8,10.3,29.5,10.1z"/>
<path id="hair-left" fill="var(--color-hair-left)" d="M18.4,9.9c0.5-0.2,0.8-0.8,0.6-1.3C18.8,8.2,18.4,8,18,8c0,0,0,0,0,0c0-0.6-0.5-1-1-1C16.4,7,2,7.7,2,34 c0,0.6,0.4,1,1,1s1-0.4,1-1c0-19.6,8.1-23.8,11.6-24.7C12.2,11.6,6,17.9,6,32.4V37c0,0.6,0.4,1,1,1s1-0.4,1-1v-4.6 C8,14.4,18,10.1,18.4,9.9z"/>
<path id="hair-left" fill="var(--color-hair-left2)" d="M18.5,10.1C18.2,10.3,10,14.9,10,32v8c0,0.6,0.4,1,1,1s1-0.4,1-1v-8c0-15.8,7.4-20.1,7.5-20.1 c0.5-0.3,0.7-0.9,0.4-1.4C19.6,10,19,9.9,18.5,10.1z"/>
<path id="eye-right" fill="var(--color-eye-right)" d="M25,24.9c0,0,0.2,1.3,0.6,1.7s3.3,2.5,5.9-0.9c1.2-1.5,0.6-3.8,0.6-3.8S29.4,24.1,25,24.9z"/>
<circle id="pupil-right" cx="28" cy="25" r="1.5" fill="var(--color-pupil-right)" />
<path id="eye-left" fill="var(--color-eye-left)" d="M15.8,21.8c0,0-0.6,2.3,0.6,3.8c2.6,3.4,5.5,1.4,5.9,0.9c0.4-0.4,0.6-1.7,0.6-1.7 C18.6,24.1,15.8,21.8,15.8,21.8z"/>
<circle id="pupil-left" fill="var(--color-pupil-left)" cx="20" cy="25" r="1.5" fill="red" />
<ellipse id="ellipse1" fill="var(--color-ellipse1)" cx="24" cy="15" rx="12" ry="10"/>
<ellipse id="ellipse2" fill="var(--color-ellipse2)" cx="24" cy="13.8" rx="10" ry="7.8"/>
<ellipse id="ellipse3" fill="var(--color-ellipse3)" cx="24.2" cy="12.2" rx="8" ry="6.2"/>
</symbol>
<svg class="monstr-colors">
<use xlink:href="#monstr" />
</svg>
</svg>
Below is a combined example with styling three instances of the same image.
Each instance of the created <use xlink: href = "# monstr"/> has its own color scheme, which is linked to the nested svg class.
<div class="container">
<svg class="color-monstr">
<use xlink:href="#monstr" transform="scale(3)" />
</svg>
</div>
<div class="container2">
<svg class="color-monstr2">
<use xlink:href="#monstr" transform="scale(2)" />
</svg>
</div>
<div class="container3">
<svg class="color-monstr3">
<use xlink:href="#monstr" transform="scale(3)" />
</svg>
</div>
With :hover, each instance replaces the color scheme with the color scheme of the adjacent instance.
.parent {
position:relative;
}
.container {
width:400px;
height:400px;
position:absolute;
top:0;
}
.container2 {
position: absolute;
top:0;
left:150px;
}
.container3 {
position: absolute;
top:0;
left:240px;
}
.color-monstr {
--color-ears: #459E48;
--color-horn-right: #388E3C;
--color-horn-left: #388E3C;
--color-face:#4CAF50;
--circle-horn-left:#8BC34A;
--circle-horn-right:#8BC34A;
--eye-right:#FFF9C4;
--eye-left:#FFF9C4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#173027;
}
.color-monstr:hover {
--color-ears: #504F7A;
--color-horn-right: #504FF6;
--color-horn-left: #504FF6;
--color-face:#807FC4;
--circle-horn-left:#FF00AE;
--circle-horn-right:#FF00AE;
--eye-right:#FFDBF4;
--eye-left:#FFDBF4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#FFDBF4;
}
.color-monstr2 {
--color-ears: #504F7A;
--color-horn-right: #504FF6;
--color-horn-left: #504FF6;
--color-face:#807FC4;
--circle-horn-left:#FF00AE;
--circle-horn-right:#FF00AE;
--eye-right:#FFDBF4;
--eye-left:#FFDBF4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#FFDBF4;
}
.color-monstr2:hover {
--color-ears: #770051;
--color-horn-right: #388E3C;
--color-horn-left: #388E3C;
--color-face:#FFDD00;
--circle-horn-left:#D0FF00;
--circle-horn-right:#A0C400;
--eye-right:#FFF9C4;
--eye-left:#FFF9C4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#FFF9C4;
}
.color-monstr3 {
--color-ears: #770051;
--color-horn-right: #388E3C;
--color-horn-left: #388E3C;
--color-face:#FFDD00;
--circle-horn-left:#D0FF00;
--circle-horn-right:#A0C400;
--eye-right:#FFF9C4;
--eye-left:#FFF9C4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#FFF9C4;
}
.color-monstr3:hover {
--color-ears: #459E48;
--color-horn-right: #388E3C;
--color-horn-left: #388E3C;
--color-face:#4CAF50;
--circle-horn-left:#8BC34A;
--circle-horn-right:#8BC34A;
--eye-right:#FFF9C4;
--eye-left:#FFF9C4;
--pupil-right:#263238;
--pupil-left:#263238;
--mouth:#173027;
}
<div class="parent">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" >
<symbol id="monstr">
<path id="ears"
fill="var(--color-ears)"
d="M12,31c-2.3,0-3.7-3.2-4-5c0.7-1.3,3.3-2,4-2c5.7-2.4,17.8-2.9,24,0c0.7,0,3.3,0.7,4,2c-0.3,1.8-1.7,5-4,5 C33.6,32.8,14.7,34.2,12,31z"/>
<g>
<path id="horn-right"
fill="var(--color-horn-right)" d="M40,8c-0.6,0-1,0.4-1,1c0,2.7-3.3,5-6,5c-0.6,0-1,0.4-1,1s0.4,1,1,1c3.7,0,8-3.1,8-7C41,8.4,40.6,8,40,8z"/>
<path id="horn-left"
fill="var(--color-horn-left)" d="M8,8c0.6,0,1,0.4,1,1c0,2.7,3.3,5,6,5c0.6,0,1,0.4,1,1s-0.4,1-1,1c-3.7,0-8-3.1-8-7C7,8.4,7.4,8,8,8z"/>
</g>
<path id="face"
fill="var(--color-face)" d="M12,31v-7c0-9.2,5.3-16,12-16s12,6.8,12,16v7c-1.2,5.6-7,12-12,12S13.2,36.6,12,31z"/>
<g>
<circle id="circle-horn-left" fill="var(--circle-horn-left)" cx="8" cy="9" r="3"/>
<circle id="circle-horn-right" fill="var(--circle-horn-right)" cx="40" cy="9" r="3"/>
</g>
<g>
<ellipse id="eye-right" fill="var(--eye-right)" cx="29" cy="26" rx="2" ry="4"/>
<ellipse id="eye-left" fill="var(--eye-left)" cx="19" cy="26" rx="2" ry="4"/>
</g>
<g>
<circle id="pupil-right" fill="var(--pupil-right)" cx="29" cy="27" r="1"/>
<circle id="pupil-left" fill="var(--pupil-left)" cx="19" cy="27" r="1"/>
</g>
<path id="mouth" fill="var(--mouth)" d="M24,33c-4,0-5.8,3-5.8,3s2.6,0,5.8,0s5.8,0,5.8,0S28,33,24,33z"/>
</symbol>
</svg>
<div class="container">
<svg class="color-monstr">
<use xlink:href="#monstr" transform="scale(3)" />
</svg>
</div>
<div class="container2">
<svg class="color-monstr2">
<use xlink:href="#monstr" transform="scale(2)" />
</svg>
</div>
<div class="container3">
<svg class="color-monstr3">
<use xlink:href="#monstr" transform="scale(3)" />
</svg>
</div>
</div>
Here is a better way or how I color my SVGs. As Inline SVGs have a bitter taste on readability of the rest of the code and adding them as background or mask, they can not be colored by a dark theme switch. Include them externally and load them inside an html object:
<object id="background-anim" class="svg" aria-hidden="true" data="./media/Background-fluid-lines-anim.svg" type="image/svg+xml"></object>
This SVG is now added externally.
To set the colors you need to set for the desired colors a class inside of the SVG.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">
<defs>
<style>
.svg-element__clrText{
fill:rgb(255,255,255);
}
.svg-element__clrPrimary{
fill:rgb(155,155,155);
}
.svg-element__clrBackground{
fill:rgb(55,55,55);
}
</style>
</defs>
<path class="svg-element__clrText"></path>
</svg>
In your paths, you will set those classes to the desired elements that should adapt colors.
Now you will manipulate those fill values with JavaScript and add the correct CSS Custom Porperties:
/*Optional: Listening to the clicked switch if you have one*/
document.querySelectorAll('.theme-toggle').forEach((toggle) => {
toggle.addEventListener('click', () => themeToggle);
});
window.themeToggle = function themeToggle() {
document.documentElement.classList.toggle('darkMode');
//this .darkmode{} class changes the values of my variables set to white mode in the ':root{}' in the css file
loadTheme()
}
function loadTheme(){
/* For loading more than just the colors */
loadThemeIcon();
loadSVGColors();
}
/* Now here comes the important part */
function loadSVGColors() {
const svgs = document.querySelectorAll('.svg'); //getting NodeList of SVGs
const style = getComputedStyle(document.body), //getting CSS variables inside of js
svgs.forEach(svg => {
element = svg.contentDocument; //get the actual svg that is loaded into the object element
const clrText = svg.querySelectorAll('.svg-element__textClr'), //searching inside of the SVG after my classes
textClr.forEach(element => { //NodeList to Array
element.style.fill = style.getPropertyValue('--clr-text');//whatever variables you have set or you can toggle a class that has only this css variable inside
});
/* [...and so on]*/
const primeClr = element.querySelectorAll('.svg-element__primeClr');
primeClr.forEach(e => {
e.style.fill = style.getPropertyValue('--clr-primary');
});
});
}
I guess there is a better performance when you add the SVGs inside the HTML with fill: var(--clr-text), however after having 50kb of code per SVG leads to lots of scrolling
I know this goes further than the question but I would have been glad to find this before under these SO posts.
I stumbled upon this for a very similar case and want to share a completely different approach.
Use the css multi background feature (MDN Docs)
First you need to make the part of your svg that you want to color transparent with fill="transparent"
Now you can just specify multiple backgrounds, where one can be your variable, for example
body {
background: url('path/to/your/svg/or/data-url'), var(--background);
}
If you need to control only one color, you can use currentColor keyword in the fill property and change it through css color property.
.icon {
color: var(--primary-color);
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129'%3E%3Cpath d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='currentColor' /%3E%3C/svg%3E");
}
<path class="class-name"/>
:root {
--color : #123456;
}
.class-name {
fill : var(--color)
}
try this

What is wrong with my SVG Path Code?

I'm following this code pen but the author's code doesn't work for my own custom SVG from Illustrator. The original author puts a fill as an inline CSS style on the SVG path code. The white hover fill won't work if I don't make the SVG path code to white.
By default - The image is invisible but should be color #788F9B.
On hover it works:
a svg:hover #bino {
fill: #fff;
}
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 209.84 136.85">
<path id="bino" d="M58.07,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55A22.34,22.34,0,0,0,81.2,123.15v-2.66A22.86,22.86,0,0,1,58.07,139.42Z" transform="translate(-10.14 -29.37)" style="fill:#29aae1" />
<path d="M172.65,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55,22.34,22.34,0,0,0,23.13-21.52v-2.66A23.28,23.28,0,0,1,172.65,139.42Z" transform="translate(-10.14 -29.37)" style="fill:#29aae1" />
<path d="M204.72,82.65h0l-43.63-47.3a29.17,29.17,0,0,0-24.18-4.2,21,21,0,0,0-16.29,21v2.63a15.35,15.35,0,0,0-4.73-1.05,14,14,0,0,0-6.31,1.58l0.53-4.2a21,21,0,0,0-16.29-21,29.75,29.75,0,0,0-23.65,4.73L25.48,83.18h0a47.88,47.88,0,1,0,80.42,35.22v-5.26a11.25,11.25,0,0,0,8.94,4.2,11.93,11.93,0,0,0,9.46-4.73v5.78a47.83,47.83,0,0,0,95.66,0A46.83,46.83,0,0,0,204.72,82.65ZM58.07,151.51a33.11,33.11,0,1,1,33.11-33.11h0a33,33,0,0,1-32.8,33.11H58.07Zm114.58,0a33.11,33.11,0,1,1,33.11-33.11h0A33,33,0,0,1,173,151.51h-0.32Z" transform="translate(-10.14 -29.37)" style="fill:#fff" />
</svg>
</a>
It doesn't work because the style attributes in HTML have precedence over the CSS stylesheet. Hence the color never changes.
You can solve this by defining the initial color in your stylesheet instead:
#bino {
fill: #29aae1;
}
a:hover #bino {
fill: #fff;
}
A working example:
a {
display: block;
width: 166px;
padding: 30px;
}
a:hover {
background-color: #166584;
}
.bino {
fill: #29aae1;
}
#binocular {
fill: #788F9B;
}
a:hover #binocular {
fill: #fff;
}
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 209.84 136.85">
<path class="bino" d="M58.07,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55A22.34,22.34,0,0,0,81.2,123.15v-2.66A22.86,22.86,0,0,1,58.07,139.42Z" transform="translate(-10.14 -29.37)" />
<path class="bino" d="M172.65,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55,22.34,22.34,0,0,0,23.13-21.52v-2.66A23.28,23.28,0,0,1,172.65,139.42Z" transform="translate(-10.14 -29.37)" />
<path id="binocular" d="M204.72,82.65h0l-43.63-47.3a29.17,29.17,0,0,0-24.18-4.2,21,21,0,0,0-16.29,21v2.63a15.35,15.35,0,0,0-4.73-1.05,14,14,0,0,0-6.31,1.58l0.53-4.2a21,21,0,0,0-16.29-21,29.75,29.75,0,0,0-23.65,4.73L25.48,83.18h0a47.88,47.88,0,1,0,80.42,35.22v-5.26a11.25,11.25,0,0,0,8.94,4.2,11.93,11.93,0,0,0,9.46-4.73v5.78a47.83,47.83,0,0,0,95.66,0A46.83,46.83,0,0,0,204.72,82.65ZM58.07,151.51a33.11,33.11,0,1,1,33.11-33.11h0a33,33,0,0,1-32.8,33.11H58.07Zm114.58,0a33.11,33.11,0,1,1,33.11-33.11h0A33,33,0,0,1,173,151.51h-0.32Z" transform="translate(-10.14 -29.37)" />
</svg>
</a>

How can I change the color of an 'svg' element?

I want to use this technique and change the SVG color, but so far I haven't been able to do so. I use this in the CSS, but my image is always black, no matter what.
My code:
.change-my-color {
fill: green;
}
<svg>
<image class="change-my-color" xlink:href="https://svgur.com/i/AFM.svg" width="96" height="96" src="ppngfallback.png" />
</svg>
2020 answer
CSS Filter works on all current browsers
To change any SVGs color
Add the SVG image using an <img> tag.
<img src="dotted-arrow.svg" class="filter-green"/>
To filter to a specific color, use the following Codepen (click here to open the codepen) to convert a hexadecimal color code to a CSS filter:
For example, output for #00EE00 is
filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
Add the CSS filter into this class.
.filter-green{
filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
}
To change the color of any SVG, you can directly change the SVG code by opening the SVG file in any text editor. The code may look like the below code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
<g>
<path d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
C181.113,454.921,171.371,464.663,161.629,474.404z"/>
/* Some more code goes on */
</g>
</svg>
You can observe that there are some XML tags like path, circle, polygon, etc.. There you can add your own color with help of the style attribute. Look at the below example
<path fill="#AB7C94" d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
C181.113,454.921,171.371,464.663,161.629,474.404z"/>
Add the style attribute to all the tags so that you can get your SVG of your required color.
As per Daniel's comment, we can use fill attribute directly instead of fill element inside style attribute.
You can't change the color of an image that way. If you load SVG as an image, you can't change how it is displayed using CSS or JavaScript in the browser.
If you want to change your SVG image, you have to load it using <object>, <iframe> or using <svg> inline.
If you want to use the techniques in the page, you need the Modernizr library, where you can check for SVG support and conditionally display or not a fallback image. You can then inline your SVG and apply the styles you need.
See:
#time-3-icon {
fill: green;
}
.my-svg-alternate {
display: none;
}
.no-svg .my-svg-alternate {
display: block;
width: 100px;
height: 100px;
background-image: url(image.png);
}
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206
C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161
C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505
c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081
c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"/>
</svg>
<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />
You can inline your SVG. Tag your fallback image with a class name (my-svg-alternate):
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" .../>
</svg>
<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />
And in CSS use the no-svg class from Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ) to check for SVG support. If there isn't any SVG support, the SVG block will be ignored and the image will be displayed, otherwise the image will be removed from the DOM tree (display: none):
.my-svg-alternate {
display: none;
}
.no-svg .my-svg-alternate {
display: block;
width: 100px;
height: 100px;
background-image: url(image.png);
}
Then you can change the color of your inlined element:
#time-3-icon {
fill: green;
}
If you want to change the color dynamically:
Open the SVG in a code editor
Add or rewrite the attribute of fill of every path to fill="currentColor"
Now, that svg will take the color of your font color, so you can do something like:
svg {
color : "red";
}
Only SVG with path information. You can't do that to the image... as the path you can change stroke and fill information and you are done. like Adobe Illustrator
So, via CSS you can overwrite the path fill value:
path { fill: orange; }
But if you want a more flexible way as you want to change it with a text when having some hovering effect going on, use:
path { fill: currentColor; }
body {
background: #ddd;
text-align: center;
padding-top: 2em;
}
.parent {
width: 320px;
height: 50px;
display: block;
transition: all 0.3s;
cursor: pointer;
padding: 12px;
box-sizing: border-box;
}
/*** desired colors for children ***/
.parent{
color: #000;
background: #def;
}
.parent:hover{
color: #fff;
background: #85c1fc;
}
.parent span{
font-size: 18px;
margin-right: 8px;
font-weight: bold;
font-family: 'Helvetica';
line-height: 26px;
vertical-align: top;
}
.parent svg{
max-height: 26px;
width: auto;
display: inline;
}
/**** magic trick *****/
.parent svg path{
fill: currentcolor;
}
<div class='parent'>
<span>TEXT WITH SVG</span>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" viewBox="0 0 32 32">
<path d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
</svg>
</div>
I added a test page - to color SVG via Filter settings:
For example,
filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)
Upload & Color your SVG - Jsfiddle
I took the idea from: Swapping Fill Color on Image Tag SVGs
Solution 1 - Edit SVG to point to the currentColor
<svg>... fill: currentColor stroke: currentColor ...</svg>
Then you can control the color of the stroke and the fill from your CSS content:
svg {
color: blue; /* Or any color of your choice. */
}
Pros and cons:
Simple and uses conventional supported CSS.
Suitable if:
You control the SVG
SVG can be included inline in the HTML.
Solution 2 - CSS mask property
<i class="icon"></i>
.icon {
-webkit-mask-size: cover;
mask-size: cover;
-webkit-mask-image: url(https://url.of.svg/....svg);
mask-image: url(https://url.of.svg/....svg);
background-color: blue; /* Or any color of your choice. */
width: 20px;
height: 20px;
}
}
Pros and cons
Relatively easy to use
Browser support for the mask CSS property is partial.
Suitable if:
SVG is external, and included via URL
Meant to be used on modern known browsers.
Solution 3 - CSS Filter property - static color
If the color is known in advance, you can use https://codepen.io/sosuke/pen/Pjoqqp to find the filter needed to change your SVG to the desired color. For example, to convert the svg to #00f:
<img src="https://url.of.svg/....svg" class="icon">
.icon {
filter: invert(8%) sepia(100%) saturate(6481%) hue-rotate(246deg) brightness(102%) contrast(143%);
}
If your original color isn't black, prefix the list of filters with brightness(0) saturate(100%) to convert it first to black.
Pros and cons:
There might be a small, nonsignificant difference between the result and the desired color.
Suitable if:
Desired color is known in advance.
External image
SVG mask on a box element with a background color will result:
body{ overflow:hidden; }
.icon {
--size: 70px;
display: inline-block;
width: var(--size);
height: var(--size);
transition: .12s;
-webkit-mask-size: cover;
mask-size: cover;
}
.icon-bike {
background: black;
animation: 4s frames infinite linear;
-webkit-mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg);
mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg);
}
#keyframes frames {
0% { transform:translatex(100vw) }
25% { background: red; }
75% { background: lime; }
100% { transform:translatex(-100%) }
}
<i class="icon icon-bike" style="--size:150px"></i>
Note - SVG masks are not supported in Internet Explorer browsers
The easiest way would be to create a font out of the SVG using a service like https://icomoon.io/app/#/select or such. Upload your SVG, click "generate font", include font files and CSS content into your side and just use and style it like any other text. I always use it like this because it makes styling much easier.
But as mentioned in the article commented by #CodeMouse92, icon fonts mess up screen readers (and are possibly bad for SEO). So rather stick to the SVGs.
You can try to color it with this css filter hack:
.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);
}
To simply change the color of the SVG file:
Go to the SVG file and under styles, mention the color in fill:
<style>.cls-1{fill: #FFFFFF;}</style>
To change the color of an SVG element, I have found out a way while inspecting the Google search box search icon below:
.search_icon {
color: red;
fill: currentColor;
display: inline-block;
width: 100px;
height: 100px;
}
<span class="search_icon">
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg>
</span>
I have used a span element with "display:inline-block", height, width and setting a particular style "color: red; fill: currentColor;" to that span tag which is inherited by the child svg element.
Target the path within the 'svg' tag:
<svg>
<path>....
</svg>
You can do it inline, like:
<path fill="#ccc">
Or
svg{
path{
fill: #ccc
You can change SVG coloring with CSS if you use some tricks.
I wrote a small script for that.
go through a list of elements which do have an SVG image
load the SVG file as XML
fetch only the SVG part
change color of path
replace src with the modified SVG image as an inline image
$('img.svg-changeable').each(function () {
var $e = $(this);
var imgURL = $e.prop('src');
$.get(imgURL, function (data) {
// Get the SVG tag, ignore the rest
var $svg = $(data).find('svg');
// Change the color
$svg.find('path').attr('fill', '#000');
$e.prop('src', "data:image/svg+xml;base64," + window.btoa($svg.prop('outerHTML')));
});
});
The code above might not be working correctly. I've implemented this for elements with an SVG background image which works nearly similar to this.
But anyway, you have to modify this script to fit your case.
Method 1
The easy and effect way:
Open your .svg file with any text editor
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 477.526 477.526" style="enable-background:new 0 0 477.526 477.526;
fill: rgb(109, 248, 248);" xml:space="preserve">
<svg />
Give an style attribute and fill that with color.
Another way
Fill with color in your shape. Here i have rect shape fill="white".
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
<g>
<title>background</title>
<rect fill="#fff" id="canvas_background" height="602" width="802" y="-1"
x="-1"/>
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%"
id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%"
width="100%"/>
</g>
</g>
</svg>
2022 Web Component <load-file> answer
This (8 line) native Web Component loads external content, and injects it into the DOM.
It is explained and documented in a DEV blog post: <load-file> Web Component.
Full source code:
customElements.define("load-file", class extends HTMLElement {
// declare default connectedCallback as sync so await can be used
async connectedCallback(
// call connectedCallback with parameter to *replace* SVG (of <load-file> persists)
src = this.getAttribute("src"),
// attach a shadowRoot if none exists (prevents displaying error when moving Nodes)
// declare as parameter to save 4 Bytes: 'let '
shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"})
) {
// load SVG file from src="" async, parse to text, add to shadowRoot.innerHTML
shadowRoot.innerHTML = await (await fetch(src)).text()
// append optional <tag [shadowRoot]> Elements from inside <load-svg> after parsed <svg>
shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))
// if "replaceWith" attribute
// then replace <load-svg> with loaded content <load-svg>
// childNodes instead of children to include #textNodes also
this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
}
})
<load-file src="//load-file.github.io/heart.svg">
<!-- elements inside load-file are MOVED to shadowDOM -->
<style shadowRoot>
svg {
height: 180px; /* Stack Overflow subwindow height */
}
path:nth-child(2n+2) {
fill: GREEN; /* shadowDOM style does NOT style global DOM */
}
</style>
</load-file>
If the same SVG must be used multiple times with different colors, define the set of paths within a hidden SVG which serves as the master copy. Then place new instances which refer to the master path with their individual fills.
Note: This approach only works with inline <svg> tags. It will not work with <img> tags loading .svg files.
:root {
fill: gray;
}
.hidden {
display: none;
}
svg {
width: 1em;
height: 1em;
}
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="hidden">
<path id="s_fave" d="m379 21c-57 0-104 53-123 78-19-25-66-78-123-78-74 0-133 68-133 151 0 45 18 88 49 116 0.5 0.8 1 2 2 2l197 197c2 2 5 3 8 3s5-1 8-3l206-206c2-2 3-3 5-5 0.8-0.8 1-2 2-3 23-28 35-64 35-102 0-83-60-151-133-151z"/>
<path id="s_star" d="m511 196c-3-10-13-18-23-19l-148-13-58-137c-4-10-14-17-25-17-11 0-21 6-25 17l-58 137-148 13c-11 1-20 8-23 19-3 10-0.3 22 8 29l112 98-33 145c-2 11 2 22 11 28 5 3 10 5 16 5 5 0 10-1 14-4l127-76 127 76c9 6 21 5 30-1 9-6 13-17 11-28l-33-145 112-98c8-7 11-19 8-29z"/>
</svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_fave"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_star"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_fave" fill="red"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_star" fill="gold"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_fave" fill="purple"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_star" fill="silver"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_fave" fill="pink"></use></svg>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><use href="#s_star" fill="blue"></use></svg>
Here the fast and furious way :)
body {
background-color: #DEFF05;
}
svg {
width: 30%;
height: auto;
}
svg path {
color: red;
fill: currentcolor;
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 514.666 514.666"><path d="M514.666,210.489L257.333,99.353L0,210.489l45.933,19.837v123.939h30V243.282l33.052,14.274v107.678l4.807,4.453 c2.011,1.862,50.328,45.625,143.542,45.625c93.213,0,141.53-43.763,143.541-45.626l4.807-4.452V257.557L514.666,210.489z M257.333,132.031L439,210.489l-181.667,78.458L75.666,210.489L257.333,132.031z M375.681,351.432 c-13.205,9.572-53.167,33.881-118.348,33.881c-65.23,0-105.203-24.345-118.348-33.875v-80.925l118.348,51.112l118.348-51.111 V351.432z"></path></svg>
For example, in your HTML:
<body>
<svg viewBox="" width="" height="">
<path id="struct1" fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
</svg>
</body>
Use jQuery:
$("#struct1").css("fill", "<desired colour>");
Check out this code. It works.
<div>
<!-- YouTube -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="white"
d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" />
</svg>
<!-- Instagram -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="white"
d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" />
</svg>
</div>
CSS
svg {
fill: white;
}
For a better resolution about Manish Menaria's (thank you so much for your help) response, use this filter generator instead a purposed generator: https://angel-rs.github.io/css-color-filter-generator/
.filter-green{
filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
}
Use an svg <mask> element.
This is better than other solutions because:
Closely matches your original code.
Works in IE!
The embedded image can still be an external, unmodified file.
The image does not even have to be an SVG.
Color is inherited from font-color, so easy to use alongside text.
Color is a normal CSS color, not a strange combination of filters.
<svg style="color: green; width: 96px; height: 96px" viewBox="0 0 100 100" preserveAspectRatio="none">
<defs>
<mask id="fillMask" x="0" y="0" width="100" height="100">
<image xlink:href="https://svgur.com/i/AFM.svg" x="0" y="0" width="100" height="100" src="ppngfallback.png" />
</mask>
</defs>
<rect x="0" y="0" width="100" height="100" style="stroke: none; fill: currentColor" mask="url("#fillMask")" />
</svg>
https://jsfiddle.net/jamiegl/5jaL0s1t/19/
If you want to do this to an inline SVG file, that is, for example, a background image in your CSS content:
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='rgba(31,159,215,1)' viewBox='...'/%3E%3C/svg%3E");
Of course, replace the ... with your inline image code.
There are some problems with Manish Menaria's answer, if we convert white color it shows gray.
So I added some tweaks, and the below example specifically shows how to change the color in the material icon:
<mat-icon class="draft-white" svgIcon="draft" aria-hidden="false"></mat-icon>
.draft-white{
filter: brightness(0) invert(1);
}
You can use a font icon to use any CSS option in SVG
I was searching for a way to have any CSS options, like animation for SVG, and I ended up to generate a font icon with my SVG(s) and then used it inside a span (like Font Awesome), so any CSS option, like coloring, was available on it.
I used https://icomoon.io to convert my SVG image to a font icon. Then you can use it like Font Awesome or MaterialIcon inside HTML elements.
I found it a bit clumsy, but it is definitely a working way to dynamically change the color of an SVG included with <img> tag.
In the SVG file, you can add CSS content the following way:
<svg ...>
<defs>
<style>
...
<style>
<defs>
There you can use #media rules, with which the SVG can look outside itself for contextual circumstances. There's an aspect-ratio media feature that applies to the SVG box (e.g., the <img> tag). You can create different contexts for the SVG by stretching the SVG box a little bit.
This way you can also make the favicon the same SVG that appears on the website, but with a different color. (In this case, no other SVG boxes should be square-shaped.)
/* img stretched horizontally (if SVG is square-shaped) */
#media (min-aspect-ratio: 1000/999) {
path {
fill: blue;
}
}
/* img stretched vertically (if SVG is square-shaped) */
#media (max-aspect-ratio: 999/1000) {
path {
fill: green;
}
}
/* img with exact sizes */
#media (aspect-ratio: 86/74) {
path {
fill: red;
}
}
/* favicon with light browser theme */
#media (aspect-ratio: 1/1) and (prefers-color-scheme: light) {
path {
fill: black;
}
}
/* favicon with dark browser theme */
#media (aspect-ratio: 1/1) and (prefers-color-scheme: dark) {
path {
fill: white;
}
}
One very important thing
The SVG must contain viewBox information, so that the stretching does not affect the graphics. Example:
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 300 300">
Actually, there is a quite more flexible solution to this problem: writing a Web Component which will patch SVG as text at runtime. I also published in a gist with a link to JSFiddle.
👍 filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
<html>
<head>
<title>SVG with color</title>
</head>
<body>
<script>
(function () {
const createSvg = (color = '#ff9933') => `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="76px" height="22px" viewBox="-0.5 -0.5 76 22">
<defs/>
<g>
<ellipse cx="5" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
<ellipse cx="70" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
<path d="M 9.47 12.24 L 17.24 16.12 Q 25 20 30 13 L 32.5 9.5 Q 35 6 40 9 L 42.5 10.5 Q 45 12 50 6 L 52.5 3 Q 55 0 60.73 3.23 L 66.46 6.46" fill="none" stroke="#ff9933" stroke-miterlimit="10" pointer-events="stroke"/>
</g>
</svg>`.split('#ff9933').join(color);
function SvgWithColor() {
const div = Reflect.construct(HTMLElement, [], SvgWithColor);
const color = div.hasAttribute('color') ? div.getAttribute('color') : 'cyan';
div.innerHTML = createSvg(color);
return div;
}
SvgWithColor.prototype = Object.create(HTMLElement.prototype);
customElements.define('svg-with-color', SvgWithColor);
document.body.innerHTML += `<svg-with-color
color='magenta'
></svg-with-color>`;
})();
</script>
</body>
</html>
My answer would be this. But I’m not 100% sure if it works for everyone:
Select 'svg' and then 'path'. And you can change 'fill' then.
.eye-icon-container {
width: 33px;
height: 33px;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
:hover {
background-color: #ddf0ff;
}
:active {
background-color: #1d398d;
svg {
path {
fill: #fff;
}
}
}
}
If you have a single-colour SVG with varying opacities that you simply want to tint to a different colour then there is another approach that can be used: the feFlood SVG filter.
This solution is not as straightforward as a single-line CSS, however:
It works on SVGs inside of an img element.
This doesn't require editing the source SVG at all.
It allows you to simply choose a target colour for the SVG and not worry about complex colour transforms, like hue-rotate.
Here is an example:
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<defs>
<filter id="recolourFilter" filterUnits="userSpaceOnUse">
<feFlood flood-color="aquamarine" result="flood" />
<feComposite in="flood" in2="SourceAlpha" operator="in" />
</filter>
</defs>
</svg>
<img style="filter: url(#recolourFilter);" width="300" src="https://upload.wikimedia.org/wikipedia/commons/6/6b/Bitmap_VS_SVG.svg" />
In the above example, we create an inline SVG to define the filters and then we apply it to the image. Inside of the <filter> block we first define the fill colour that we want via <feFlood> and then we create a composite image using the alpha channel of the source plus the flood colour. Finally, the filter is applied to the whole image via the filter CSS property on the img element.
I learned about this technique from this Smashing Magasine article. It's a highly recommended read if you want to learn more about SVG filters.
A few additional things to note:
This filter can be applied to any HTML element via the CSS filter property.
The same filter can be reused multiple times on the same page.
If you are using an inline SVG then the <defs> block can form part of the svg element and the filter can still be applied to the whole SVG or on selective elements. This avoids needing a separate SVG element for the filters.
A good approach is to use a mixin to control stroke colour and fill colour. My 'svg's are used as icons.
#mixin icon($color, $hoverColor) {
svg {
fill: $color;
circle, line, path {
fill: $color
}
&:hover {
fill: $hoverColor;
circle, line, path {
fill: $hoverColor;
}
}
}
}
You can then do the following in your SCSS file:
.container {
#include icon(white, blue);
}

Style SVG circle with CSS

So I have my SVG-circle.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="168" cy="179" r="59" fill="white" />
</svg>
I want it to be 120% when one hover the circle. I tried both with width, height and stroke. Haven't find any solution to make the circle bigger when hovering. Any suggestions?
circle:hover
{
stroke-width:10px;
}
circle:hover
{
height: 120%;
width: 120%;
}
Want to only use CSS? Use line instead of circle.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<style>
.circle {
stroke-width: 59;
stroke-linecap: round;
}
.circle:hover {
stroke-width: 71;
}
</style>
<line x1="168" y1="179" x2="168" y2="179" stroke="white" class="circle" />
</svg>
http://jsfiddle.net/rLk7rd8b/
As per the SVG 1.1 specification you can't style the r attribute of an SVG circle using CSS https://www.w3.org/TR/SVG/styling.html#SVGStylingProperties. But you can do:
<circle cx="168" cy="179" r="59"
fill="white" stroke="black"
onmouseover="evt.target.setAttribute('r', '72');"
onmouseout="evt.target.setAttribute('r', '59');"/>
In SVG 2, which is partially supported by some modern browsers, you can style the r attribute of circles using CSS. https://www.w3.org/TR/SVG2/styling.html#PresentationAttributes
It can be done in CSS(3), by setting the transform-origin of the circle to its center and then using scale transformation:
circle {
transform-origin: center center;
}
circle:hover {
stroke-width: 10px;
transform:scale(1.2, 1.2);
}
As Phillip suggested in the comment above you can do this with CSS 3 transform.
circle:hover {
-webkit-transform: scale(x, y);
}
("-webkit" prefix is for Chrome only)
See https://developer.mozilla.org/en-US/docs/Web/CSS/transform
Here's a working example with CSS transitions too: http://jsbin.com/sozewiso/2
Click "Run code snippet" to test it out:
.myCircle:hover {
r: 20
}
.myCircle {
transition: ease 1s
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle class="myCircle" cx="10" cy="10" r="5" fill="black" />
</svg>
I stumbled across this page but wanted to add my own answer that I think is easiest. Apparently it doesn't work in Firefox though, which is why someone downvoted.
Step 1: Add a class (e.g. "myCircle") to your circle
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle class="myCircle" cx="168" cy="179" r="59" fill="white" />
</svg>
Step 2: In your CSS file you can use "r" as a CSS property!
.myCircle:hover {
r: 100;
}
Step 3 (optional): Feel free to add a transition to make the radius grow smoothly:
.myCircle {
transition: all 1s;
}
This should work for you.
jsfiddle
You need to manipulate the radius and this can only be done via javascript:
$(function () {
$("svg circle").on("mouseenter", function () {
var oldR = $(this).attr("r");
var newR = (((oldR*2)/100)*120)/2; // 120% width
$(this).attr("r", newR);
});
});
I am not sure, but you can not full custom a svg only with css. However, if you will do it won't be cross browser.
In the past I used svg for creating a complex map and for me the solution was rapheljs.
EDIT:
Using #phonicx calculus for radius i modified the code, having something which is able to customize each circle ( in case if you have more ) :
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle data-precentage='100' cx="168" cy="179" r="59" fill="red" />
<circle data-precentage='120' cx="74" cy="100" r="59" fill="black" />
</svg>
You forgot the stroke color:
circle:hover {
stroke:white;
stroke-width:10px;
}
I was working on something else and came across this question. I'm doing something similar and using greensock. I animated the scale on a couple circles using Greensock, GSAP. I needed to animate tranformOrigin and the scale property:
TweenMax.staggerFrom(".circle",1,{scale:0,transformOrigin:"50% 50%",ease:Bounce.easeOut}, .08);
Example
https://codepen.io/grmdgs/pen/RgjdPv
Greensock
https://greensock.com/
If you want to scale it, try with transform: scale(1,5),
so you don't need to change cx,cy,r attributes.
Using JQUERY:
$(function () {
$('circle').hover(function() {
$(this).attr('r', 100);
}, function() {
$(this).attr('r', 59);
});
});
Demo Here

Resources