如何设置 SVG <g> 元素的样式?

Posted

技术标签:

【中文标题】如何设置 SVG <g> 元素的样式?【英文标题】:How to style SVG <g> element? 【发布时间】:2013-09-12 21:15:26 【问题描述】:

我有一些 SVG 元素组合在一个 &lt;g&gt; 元素中。我只想设置 &lt;g&gt; 元素的样式以显示元素分组。就像我想给它一些背景颜色和边框一样。如何实现?

我尝试将fillstroke 属性赋予&lt;g&gt; 元素,但它不起作用。怎么可能?提前致谢!

Sample Here

<svg   xmlns="http://www.w3.org/2000/svg">
    <g fill="blue" stroke="2">
            <rect id="svg_6"   y="105" x="136" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke- stroke="#000000" fill="#00ff00"/>
        <ellipse fill="#FF0000" stroke="#000000" stroke- stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" cx="271" cy="156" id="svg_7" rx="64" ry="56"/>
    </g>
</svg>

【问题讨论】:

为此有几个 js 库。试试raphaeljs.com raphaeljs 可以对 svg 元素进行分组吗? 【参考方案1】:

您不能为 SVG &lt;g&gt; 元素添加样式。它的唯一目的是对孩子进行分组。这也意味着,您赋予它的样式属性会传给它的子代,因此&lt;g&gt; 上的fill="green" 意味着其子代&lt;rect&gt; 上的自动fill="green"(只要它没有自己的@ 987654326@规范)。

您唯一的选择是向 SVG 添加一个新的 &lt;rect&gt; 并相应地放置它以匹配 &lt;g&gt; 孩子的尺寸。

【讨论】:

多数情况下是这样,但有一些属性,例如 opacity,适用于 元素本身。 &lt;g&gt; 元素的子元素会继承其class 属性吗? (测试表明确实如此,这意味着您可以将 css 敏感类应用于 &lt;g&gt; 元素并让所有子级继承该类的样式属性)【参考方案2】:

你实际上不会画Container Elements

但是您可以使用内部带有“SVG”的“foreignObject”来模拟您需要的内容。

http://jsfiddle.net/VBmbP/4/

<svg   xmlns="http://www.w3.org/2000/svg">
      <foreignObject id="G"  >
        <svg>
          <rect fill="blue" stroke-   y="55" x="55" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke="#000000"/>
          <ellipse fill="#FF0000" stroke="#000000" stroke- stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" cx="155" cy="65" id="svg_7" rx="64" ry="56"/>     
        </svg>
          <style>
              #G 
                background: #cff; border: 1px dashed black;
              
              #G:hover 
                background: #acc; border: 1px solid black;
              
          </style>
      </foreignObject>
    </svg>

【讨论】:

是的,你可以,但是 foreignObject 不适合这个:developer.mozilla.org/en/docs/Web/SVG/Element/foreignObject 从这个意义上说,它并不比 rect 对象更合适。 但是你不能在矩形内嵌套元素,对吗? 到目前为止,foreignObject 浏览器的支持还非常有限。 支持增加了很多caniuse.com/#feat=mdn-api_svgforeignobjectelement【参考方案3】:

我知道在这个问题被问和回答很久之后——我确信公认的解决方案是正确的,但是当我可以实现相同或相似时,我的纯粹主义者宁愿不向 SVG 添加额外元素直接的 CSS。

虽然您确实无法以大多数方式设置 g 容器元素的样式 - 您绝对可以为其添加轮廓和样式 - 甚至在悬停 g 时更改它 - 如 sn- p.

它在一个方面不如另一个方面好 - 您可以将轮廓框放在分组元素周围 - 但不能在其后面放置背景。所以它并不完美,不会为每个人解决问题 - 但我宁愿用 css 完成大纲,而不是仅仅为了提供样式挂钩而在代码中添加额外的元素。

而且这种方法绝对可以让您在 SVG 中显示相关对象的分组。

只是一个想法。

g 
    outline: solid 3px blue;
    outline-offset: 5px;
  

g:hover 
 outline-color: red
<svg   xmlns="http://www.w3.org/2000/svg">
  <g>
    <rect fill="blue" stroke-   y="55" x="55" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke="#000000"/>
    <ellipse fill="#FF0000" stroke="#000000" stroke- stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" cx="155" cy="65" id="svg_7" rx="64" ry="56"/>     
  </g>
</svg>

【讨论】:

非常适合我的用例(只需要一个关于组内容的视觉线索) 谢谢 - 很高兴能帮上忙。快乐编码?【参考方案4】:

您赋予“g”元素的样式将应用子元素,而不是“g”元素本身。

添加一个矩形元素并围绕您要设置样式的组定位。

见:https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g

编辑:更新措辞并在 cmets 中添加小提琴。

【讨论】:

&lt;rect&gt; 不允许有形状或&lt;g&gt; 作为儿童(即使在SVG2 中也不行)。因此,它不会简单地跨越以满足其孩子的尺寸。 @Boldewyn 我的意思是图形,而不是字面意思,但我会重新措辞以明确这一点。如此处所示:jsfiddle.net/VBmbP/2

以上是关于如何设置 SVG <g> 元素的样式?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 svg:g 元素的宽度

如何使用:before伪元素设置SVG节点的样式[重复]

如何将样式应用于 SVG 元素数组

SVG USE 元素和 :hover 样式

元素属性的jQuery动画不是样式

如何在 SVG 的矩形内设置标题标签的样式? [复制]