【问题标题】:Prevent SVG CSS bleeding防止 SVG CSS 出血
【发布时间】:2019-11-12 20:09:31
【问题描述】:

所以基本上我有一个包含两个 SVG 的网页。单击时,所选的 SVG 将可见。

问题:如果首先加载具有视口 0 0 20 20 的 SVG,并且笔画宽度为 2,然后您加载另一个具有视口 0 0 2000 2000 的 SVG em>,第一个的笔画宽度被继承到第二个。第二个现在的笔画宽度为 2 而不是 200。

容器是这样的:

<div class="clearView-container">
  // svg 2
</div>
<div class="techView-container" style="display: none;">
  // svg 1
</div>

svg1:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="273.263mm" height="210.784mm" viewBox="-49.35 -56.0421 136.632 105.392">

<defs>
 <style type="text/css">
 .pen_style1 {stroke: #000000;stroke-width: 0.25;}
 .pen_style3 {stroke: #c6c6c6;stroke-width: 0.125;stroke-dasharray: 1, 0.5}
 .pen_style4 {stroke: #ff0000;stroke-width: 0.125;stroke-dasharray: 0.2, 0.5, 1, 0.5}
 .cos {stroke: #0037a0;}
 .hiddenLine {     display: none;   }
 </style>
</defs>

svg2:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="127.46mm" height="104.6mm" viewBox="-3214 -2698 6373 5230">

<defs>
 <style type="text/css">
 .pen_style1 {stroke: #000000;stroke-width: 25;}
 .pen_style3 {stroke: #c6c6c6;stroke-width: 12.5;stroke-dasharray: 100, 50}
 .pen_style4 {stroke: #ff0000;stroke-width: 12.5;stroke-dasharray: 20, 50, 100, 50}
 .cos {stroke: #0037a0;}
 .hiddenLine {     display: none;   }
 </style>
</defs>

现在clearView-container 中的 SVG 会从 techView-container 获取该属性的属性,如果这个 (svg1) 先加载的话。

有没有办法防止两个 SVG 的 &lt;defs&gt;“渗出”?

【问题讨论】:

  • 您需要将这些元素内联到您的文档中吗?如果是,为什么?
  • @Kaiido 是的,因为 svg 是由服务器生成的。对于显示的每张图片,每个 svg 的 pen_styles 都可以不同。这取决于用户设置。
  • 这并不理想,但如果您正在生成 SVG 服务器端,您可以通过在类中添加一个唯一字符串来解决此问题,这样每个 SVG 都有唯一的样式。
  • 什么样的互动?了解这一点对我们来说非常重要,因此我们可以为您提供最佳解决方案。如果它都是基于 js 的,那么您可以在 iframe 中加载您的 svg 图像并仍然在那里执行 js,而不会泄漏到主文档。如果它需要从主文档到 svg 的一些 CSS 链接,那么确实必须将 svg 内联,然后作为最后的手段,您可以考虑编辑 SVGStyleElement 的样式表,使其所有规则更加具体。
  • 是否可以为 SVG 本身添加一个 ID 并使 CSS 更具体?例如#svg1 .pen_style1?我认为如果不对 SVG 或 SVG 的加载方式进行任何更改,您就无法做到这一点。浏览器在应用之前总是会解析所有的 CSS,所以第二个内联 SVG 的样式总是会覆盖文档后面的重复标识符。

标签: javascript html css svg


【解决方案1】:

如果有人需要答案。这就是我最终这样做的方式。 我从服务器获取 svg 作为字符串。比我使用带有 ID 的@DBSs 解决方案(不能在服务器端执行,所以在这里:)

function _injectCustomCSS (svg: string): string {
  const newID = 'id' + MathLib.hashCode(svg);
  const replaceStr = /.pen/g;
  const svgDoc = new DOMParser().parseFromString(svg, 'image/svg+xml');
  svgDoc.getElementsByTagName('svg')[0].setAttribute('id', newID);
  svgDoc.getElementsByTagName('style')[0].textContent = svgDoc.getElementsByTagName('style')[0].textContent.replace(replaceStr, '#' + newID + '>.pen');

  /* ... */
  return new XMLSerializer().serializeToString(svgDoc);
};

【讨论】:

    猜你喜欢
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    相关资源
    最近更新 更多