是的,SVG内容是全球内容.
最简单、最现代的解决办法是:
create a native JavaScript Web Component (JSWC)
Wrap the innerHTML
in shadowDOM, creating the "scope" you are after,
so styles don't leak in (except for CSS properties, parts and inheritable styles)
... or leak out
赛门铁克超文本标记语言:
<svg-chevron></svg-chevron>
<svg-chevron color="green"></svg-chevron>
<svg-chevron color="blue"></svg-chevron>
<svg-chevron color="gold"></svg-chevron>
然后创建:
<svg-chevron></svg-chevron>
<svg-chevron color="green"></svg-chevron>
<svg-chevron color="blue"></svg-chevron>
<svg-chevron color="gold"></svg-chevron>
<style>
[color] { --iconhovercolor:beige }
path { fill:red!important } /* never applied to shadowDOM */
</style>
<script>
customElements.define('svg-chevron', class extends HTMLElement {
connectedCallback(){
Object.assign( this.style , {
display : "inline-block",
width : "100px",
cursor : "pointer"
});
let color = this.getAttribute("color") || "black";
let d = "m75 90-65-42 5-9 60 40 60-40 5 9zm65-71-5-9-60 40-60-40-5 9 65 42z";
this.attachShadow({mode:"open"})
.innerHTML = `<style>
path{fill:${color}}
svg:hover{background:var(--iconhovercolor,red)}
</style>
<svg viewBox="0 0 150 100">
<path d="${d}" stroke="${color}"/>
</svg>`;
this.onclick = (evt) => {
console.log("You clicked me!", color);
}
}
});
</script>
将Web组件重构为<svg-icon>
,您就拥有了自己的图标设计系统:
<svg-icon is="chevron"></svg-icon>
<svg-icon is="menu"></svg-icon>
<svg-icon is="settings"></svg-icon>
来自另一个StackOverflow问题的fish
和ice
个图标:
<style>
svg-icon { --iconhovercolor:beige; width: 120px }
</style>
<svg-icon></svg-icon>
<svg-icon is="fish" color="green"></svg-icon>
<svg-icon is="fish" color="blue"></svg-icon>
<svg-icon color="teal"></svg-icon>
<script>
customElements.define('svg-icon', class extends HTMLElement {
connectedCallback() {
Object.assign(this.style, {
display: "inline-block",
cursor: "pointer"
});
let is = this.getAttribute("is") || "ice";
let color = this.getAttribute("color") || "black";
let d = {
"fish": "m64 46s-.7 2.7-2.6 5.3c-1.9 2.5-4 3.4-4 3.4s11.53 0 21.23 2.2c9.7 2 17.5 10.12 17.5 10.12s-.8-1.2-1.8-3.02c-1-1.8.8-4.4.8-4.4s-2.7.5-5.8-.2c-3-.6-3.9-5.2-3.9-5.2s-2.8.5-6 .5-3.6-4.5-3.6-4.5-4.5 1.2-7.7-.2c-3.13-1.4-4.03-4-4.03-4zm-2.5 10.7c-24.1 0-39.4 22.62-39.4 22.62l9 3.1h-6.8s8.2 16.7 27.9 20c.7 1.4 1.8 3.5 3.4 4.8 2.6 2 7.6 3.7 7.6 3.7s-3.3-2.9-3.7-5c-.2-.9-.3-2-.3-2.9 1.6 0 3.3-.1 5.1-.3 28.33-2.7 32.43-17.7 41.13-17.7 8.8 0 21 10.6 21 10.6l-11-16.9 11-14.66c-1.6 1.66-8.1 8.76-19.1 8.76-12.5 0-21.9-15.76-45.98-15.76zm5.93 5c2.1.8 3.6 3.1 3.6 5.22 0 1.9-1.7 3.7-3.9 4.5 1.7-1.1 2.5-2.7 2.5-4.5 0-2.02-.6-4.12-2.2-5.22zm-18.03 1.3c5.2 2.62 7.6 10.12 7.6 16.82s-3 12.4-8.1 15.1c4-3.6 5.9-9 5.9-15.1 0-6.2-1.4-13.3-5.4-16.82zm-7.4 3.82c1.9 0 3.5 1.6 3.5 3.5s-1.6 3.5-3.5 3.5c-2 0-3.6-1.6-3.6-3.5s1.6-3.5 3.6-3.5zm34.03 1.2c2 .8 3.7 3.1 3.7 5.2 0 1.9-1.8 3.7-4 4.5 1.6-1.1 2.5-2.7 2.5-4.5 0-2-.5-4.1-2.2-5.2zm7.2 5.9c2.3.8 3.8 3.1 3.8 5.2 0 1.9-1.8 3.7-4 4.5 1.7-1.1 2.5-2.7 2.5-4.5 0-2-.5-4.1-2.3-5.2zm-16 1.1c2.1.8 3.6 3.1 3.6 5.2 0 1.9-1.7 3.7-3.9 4.5 1.7-1.1 2.5-2.7 2.5-4.5 0-2-.6-4.1-2.2-5.2zm7.9 6.2c2.1.8 3.7 3.1 3.7 5.2 0 1.9-1.8 3.7-3.9 4.5 1.6-1.1 2.4-2.7 2.4-4.5 0-2-.6-4.1-2.2-5.2zm-7.9 6.8c2.2.8 3.8 3.1 3.7 5.2.1 1.9-1.7 3.7-3.9 4.5 1.7-1.1 2.5-2.7 2.5-4.5 0-2-.6-4.1-2.3-5.2z",
"ice": "m15.5 39h-1.6c6.9 6.64 6.6 11.74 10.1 19.64 2.9 6.4 5.8 11.6 10.5 15.1h-12.2c-1.5 0-2.9 1.3-2.9 2.9v.1c0 1.6 1.4 2.9 2.9 2.9h94.5c1.6 0 3-1.3 3-2.9v-.1c0-1.5-1.4-2.9-3-2.9h-26.4c.1-.7.2-1.4.2-2.1 0-8.9-7.4-16.1-16.5-16.1s-16.5 7.2-16.5 16.1c-1.6.7-3.3 1.3-5 1.5-4 .4-7.5-.9-10.5-2.8-5.4-3.3-9.1-8.6-11.5-14.2-1.6-3.8-3.8-7.3-6-10.8 1 1.1 2 2.3 2.9 3.5 2.8 3.2 4.6 7.1 6.8 10.7 2.1 3.7 5.2 6.8 8.9 9.1 3 1.8 6.8 2.2 10.2 2 1.1-.1 2.3 0 3.3-.4 2.2-3 .9-7.3-.4-10.1-.5-1.1-1-2.4-1.8-3.4-1.4.7-2.9 1.4-4.3 1.9 1-2.2 3.1-4.5 1.7-5.7-1.8-1.7-3.3-3.6-5.4-5-.9 1.5-1.7 3.1-2.7 4.4-.1-2.1-.1-4.3-.3-6.5-2.6-1.6-6.1-3.34-9.5-4.34-.6.2-.2 4.04-.5 5.74-.9-2.2-1.7-4.44-2.5-6.54-3.5-.80-11.1-1.7-15.5-1.7zm5.9 41.14c0 8.2 8.7 15.4 21.9 19.6h52.5c13.2-4.2 21.9-11.4 22-19.6h-96.4z"
}[is];
this.attachShadow({mode:"open"})
.innerHTML = `<style>
path{fill:${color}}
svg{vertical-align:top}
svg:hover{background:var(--iconhovercolor,red)}
</style>
<svg viewBox="0 0 140 140"><path d="${d}" stroke="${color}"/></svg>`;
this.onclick = (evt) => {
console.log("You clicked me!", is, color);
}
}});
</script>