如果我在一个HTML体中有几个SVG元素,其中每个SVG引用一个CSS类名,并且这个类名是在其中一个SVG元素中定义的,如下所示,那么所有的SVG元素都会受到此样式的影响.我正在try 找出这是否是设计出来的,以及如何确保css类名称是定义它的SVG的本地名称.

<svg xmlns="http://www.w3.org/2000/svg" width=100 viewBox="0 0 15 10">
    <path class="iconMain" d="M7.5,9,1,4.78789l.46713-.91645L7.5,7.85543l6.03287-3.984L14,4.78789ZM14,1.91646,13.53287,1,7.5,4.98349,1.46713,1,1,1.91646l6.5,4.2121Z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width=100 viewBox="0 0 15 10">
    <defs>
        <style>
            .iconMain {
                fill: #9cbacf;
            }
        </style>
    </defs>
    <path class="iconMain"
        d="M7.5,9,1,4.78789l.46713-.91645L7.5,7.85543l6.03287-3.984L14,4.78789ZM14,1.91646,13.53287,1,7.5,4.98349,1.46713,1,1,1.91646l6.5,4.2121Z" />
</svg>

https://codepen.io/napsta32/pen/ExOPGae

推荐答案

是的,SVG内容是全球内容.

  • id个属性变为重复,在SVG之后,first个元素将使用id个属性进行<use>

  • <style>则成为全球时尚.

最简单、最现代的解决办法是:

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问题的fishice个图标:

<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>

Css相关问答推荐

NextJs - Tailwind css类样式未应用于响应屏幕

位置:固定元素只是不固定

为什么 width: 100% 在 Flex 父级中缩小这个 div ?

为什么align-content:start应用于单行项目?

设置初始大小并记住分配的最后大小

在 CSS 中,如何用破折号填充段落中每一行的空白区域?

如何使用rvest中的 node 和类提取网页数据

具有自动调整大小的自动填充行的 CSS 网格

css3比例周围的空白

如何在 CSS Grid 布局中指定行高?

如何使表格中一行的最后一个单元格占据所有剩余宽度

边框半径 + 背景 colored颜色 == 裁剪边框

如何在没有填充区域的情况下背景化 div

为什么 .class:last-of-type 不能按我的预期工作?

在 Vuejs 中拥有全局 CSS 的最佳方式

Chrome 呈现 colored颜色 的方式与 Safari 和 Firefox 不同

如何计算所需的色调旋转以生成特定 colored颜色 ?

在 react-native 中使用 flex 使项目粘在底部

如何水平对齐 span 或 div?

CSS显示:表格列应该如何工作?