iron-icon
iron-icon copied to clipboard
iron-icon color (polymer 2)
Description
How can I colorize the iron icon (with polymer css variable) if it load an external image (like png, svg)?
I set the --iron-icon-fill-color
variable in css section, but it seems not works for me.
Expected outcome
red icons
Actual outcome
black icons:
Live Demo
https://jsfiddle.net/szamok/1mk636zz/7/
Version
Polymer: 2.3.1
This is a limitation of SVGs.
When using an iconset the SVG is embedded in the page and cascades style information. When using a src path the SVG is added in an <img>
and gets its own private style tree.
The fix would be for <iron-icon>
to treat SVG differently from bitmap images - by embedding the SVG in the page.
The easiest way to do with is with a <use>
:
<svg style="fill:var(--iron-icon-fill-color, currentColor)">
<use href$="[[importPath]]../images/arrow.svg#idForGroup"></use>
</svg>
However, this only works if you have an id="idForGroup"
on the SVG <g>
that you want. I don't think this works for <iron-icon>
as it would have to make assumptions about the content of the SVG. I can't even patch your Fiddle because your SVG doesn't have id
properties set.
Put this into a little Polymer component that honours <iron-icon>
's styles:
<dom-module id="svg-icon">
<template>
<style>
:host {
display: inline-block;
align-items: center center;
justify-content: center center;
position: relative;
vertical-align: middle;
width: var(--iron-icon-width, 24px);
height: var(--iron-icon-height, 24px);
}
svg#icon {
fill: var(--iron-icon-fill-color, currentcolor);
stroke: var(--iron-icon-stroke-color, none);
width: 100%;
height: 100%;
}
</style>
<svg id="icon">
<svg id="view" preserveAspectRatio="none">
<use id="iconRef" href$="[[src]]#[[groupId]]" on-load="_setViewBox"></use>
</svg>
</svg>
</template>
<script>
// @ts-check
class SvgIcon extends Polymer.Element {
static get is() { return 'svg-icon'; }
static get properties() { return { src: String, groupId: String } }
_setViewBox(e) {
const size = this.$.iconRef.getBoundingClientRect();
this.$.view.setAttribute('viewBox', `0 0 ${size.width} ${size.height}`);
}
}
customElements.define(SvgIcon.is, SvgIcon);
</script>
</dom-module>
That works, but needs a nasty extra event on load to scale the dynamically loaded <use>
content.
Another solution would be to import the SVG content like iconsets are, but it might be easier to just collate your SVG as a new set.