如何处理串联SVG的重复ID?

时间:2018-09-19 10:04:19

标签: php css svg

我在网页上多次使用相同的SVG。 SVG通过PHP插入服务器端,如下所示:

<?php echo file_get_contents("myimage.svg"); ?>

SVG包含一个渐变,在SVG的不同实例上应该具有不同的颜色。

服务器提供的HTML文档可能类似于以下片段。相同的SVG已插入两次:

#image1 .stop1 { stop-color: #FDF39C }
#image1 .stop2 { stop-color: #FE8A77 }
#image2 .stop1 { stop-color: #64E8EA }
#image2 .stop2 { stop-color: #A79CFC }
<div id="image1">
  <svg width="256" height="256" viewBox="0 0 256 256">
    <defs>
      <linearGradient id="gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="100%"/>
      </linearGradient>
    </defs>
    <circle fill="url(#gradient1)" cx="128" cy="128" r="100" />
  </svg>
</div>
<div id="image2">
  <svg width="256" height="256" viewBox="0 0 256 256">
    <defs>
      <linearGradient id="gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="100%"/>
      </linearGradient>
    </defs>
    <circle fill="url(#gradient1)" cx="128" cy="128" r="100" />
  </svg>
</div>

问题在于SVG的两个实例都显示第一个SVG中定义的渐变。这是实际结果与预期结果的比较:

enter image description here

这样做的原因是两个内联SVG的梯度具有相同的ID gradient1,因为包含该ID的相同SVG在服务器上插入了两次。在两种情况下,圆形元素的填充都设置为url(#gradient1),浏览器将其链接到该ID的第一个出现,即第一个SVG中的渐变定义。这种行为是正确的,但就我而言,这是一个问题。

问题是:如何避免重复的ID?我使用SVGInject进行了SVG注入,这通过使ID唯一来解决了这个问题。 SVGInject只需在ID的末尾添加一个随机字符串,例如将gradient1更改为gradient1-h4w7xo82

但是,用PHP插入SVG时看不到解决方案。你能帮忙吗?

2 个答案:

答案 0 :(得分:1)

将svg文件转换为php,以便您可以将gradientId参数传递给它。

<?php
  header('Content-Type: image/svg+xml');

  echo '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
    <defs>
      <linearGradient id="' . $gradientId . '">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="100%"/>
      </linearGradient>
    </defs>
    <circle fill="url(#' . $gradientId . ')" cx="128" cy="128" r="100" />
  </svg>';
?>

答案 1 :(得分:1)

基于CSS的解决方案 我遇到了同样的问题。

上述问题的解决方案是更改css类,以使不同的css类针对不同的对象。

更改-

  1. 第二个元素的CSS类,我将其更改为#image2 .stop1-df,并附加了其他"df"
  2. 第二个元素的线性渐变ID-gradient1-df
  3. 圆圈填充网址-#gradient1-df

#image1 .stop1 { stop-color: #FDF39C }
#image1 .stop2 { stop-color: #FE8A77 }
#image2 .stop1-df { stop-color: #64E8EA }
#image2 .stop2-df { stop-color: #A79CFC }
<div id="image1">
  <svg width="256" height="256" viewBox="0 0 256 256">
    <defs>
      <linearGradient id="gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="100%"/>
      </linearGradient>
    </defs>
    <circle fill="url(#gradient1)" cx="128" cy="128" r="100" />
  </svg>
</div>
<div id="image2">
  <svg width="256" height="256" viewBox="0 0 256 256">
    <defs>
      <linearGradient id="gradient1-df">
        <stop class="stop1-df" offset="0%"/>
        <stop class="stop2-df" offset="100%"/>
      </linearGradient>
    </defs>
    <circle fill="url(#gradient1-df)" cx="128" cy="128" r="100" />
  </svg>
</div>