Fill attribute in svg can't be overwrite in mat-icon

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Fill attribute in svg can't be overwrite in mat-icon



I want to use mat-icon for svg images but I can't change fill color. The problem is svg has an attribute fill which is set to #000000 and can't be overridden in any possible way.


svg


fill


svg


fill


#000000



In component:


this._iconRegistry.addSvgIcon('close', this._sanitizer.bypassSecurityTrustResourceUrl('/assets/images/ic_clear_black_24px.svg'));



In HTML template:


<span class="auth--icon">
<mat-icon svgIcon="close"></mat-icon>
</span>



CSS:


svg
color: red !important;
fill: currentColor !important;



Chrome DevTools of element tab and styles tab



If I put this code in element.style this can be overridden.


element.style



Chrome DevTools of element tab and styles tab



For example on Angular Material svg[Attributes Style] does not have fill attribute and everything works.


svg[Attributes Style]


fill



Styles tab in Chrome DevTools



UPDATE 2018-04-12



I finally found the cause of the issue. In my reset.css file, I had defined something like this:


reset.css


svg
/*
For IE9. Without, occasionally draws shapes
outside the boundaries of <svg> rectangle.
*/
overflow: hidden;



and I can't override style for svg element in my others .scss files.


svg


.scss





Please update your question to include your actual html for the .svg icon.
– Narm
Apr 11 at 18:02





Now there is some more information what is in HTML and angular component.
– Verri
Apr 12 at 5:12




1 Answer
1



In the case of the angular material example, your CSS rule is applied because your <path> element indeed has no other fill rule set than the one it inherits from .mat-icon one (which sets it to currentColor).


<path>


fill


.mat-icon


currentColor



But when there is a fill attribute set on the <path> element, then this rule takes precedence over the inherited one.


fill


<path>



Luckily, it's still a poor rule, so you can override it quite easily:




.mat-icon
fill: red;

.mat-icon rect /* change 'rect' to whatever tag you target */
fill: green;

/* you can even set it to 'inherit' and it will work */
.mat-icon rect:hover
fill: inherit;


<div class="mat-icon">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="50" height="50">
<rect x="0" y="0" width="100" height="100" fill="orange"/>
</svg>
</div>



Now, you may face something you didn't expected which is that paths which should have fill="none" attribute now are filled.

To overcome this, you'd have to make your selector a bit more complex:


fill="none"




.mat-icon
fill: red;

/* beware it doesn't handle all possibilities of transparency, there are too many... */
.mat-icon path:not([fill='none']):not([fill="transparent"])
fill: inherit;


.bad-icon
fill: red;

.bad-icon path
fill: inherit;


<div class="mat-icon">
<svg xmlns="http://www.w3.org/2000/svg">
<path fill="none" d="M0 0h24v24H0z"></path>
<path fill="orange" d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"></path>
</svg>
</div>

<div class="bad-icon">
<svg xmlns="http://www.w3.org/2000/svg">
<path fill="none" d="M0 0h24v24H0z"></path>
<path fill="orange" d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"></path>
</svg>
</div>





The problem is not fill attribute in <path> but in <svg> like this <svg fill="#000000" . I can't override this in any way. In angualr material example ther is not fill attribute in <svg> I don't know why.
– Verri
Apr 12 at 6:18


fill


<path>


<svg>


<svg fill="#000000"


fill


<svg>





@Verri the same applies. If you set a CSS rule with higher importance, your CSS rule will win. With the current .mat-icon fill: currentColor , inherited value from <svg fill> will win, because the inheritance chain is broken. So if you wish you can just set your rule to be .mat-icon svg fill: inherit , this way you wouldn't even have issues with paths that should be fill=none. jsfiddle.net/yr6vda4p
– Kaiido
Apr 12 at 6:48



.mat-icon fill: currentColor


<svg fill>


.mat-icon svg fill: inherit


fill=none





yes, this is a normal behavior which should work. Problem was svg element in my reset.css file. I can't override this I dont know why. Very annyoing. Thanks for help anyway!
– Verri
Apr 12 at 6:54


svg


reset.css






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard