SVG USE元素和:悬停样式

Sas*_*asQ 21 css svg styling hover

我正在尝试使用CSS :hover伪类来设置<defs><use>标签嵌入的SVG元素,但它似乎不起作用: - /这是我的代码:

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
 <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/>
 <style type="text/css" media="screen">
        .active { fill: #0BE; }
        .active:hover { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
        .active2 #p2 { fill: #0BE; }
        .active2:hover #p2 { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
        #p2:hover { opacity: 0.8; stroke: #F0F; stroke-width: 4px; }
    </style>
</head>
<body>


<svg version="1.1" width="640" height="480"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">

 <defs>
  <polygon id="p0" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active"/>
  <g id="gr1">
      <polygon id="p1" points="130,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6"/>
      <polygon id="p2" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active"/>
  </g>
 </defs>

 <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)"/>
    <use xlink:href="#p0" transform="translate(250,0)"/>
    <use xlink:href="#p0" transform="translate(460,0)" class="active" />
 </g>
 <g transform="translate(100,300)">
    <polygon id="style" points="110,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="foo"/>
    <use xlink:href="#gr1" transform="translate( 350,2)" class="active2"/>
 </g>

</svg>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我希望它的工作方式是当用户将鼠标指针放在嵌入元素上时,其内部元素的类"active"将改变其样式.当我<defs>直接嵌入一​​个形状并将CSS类应用于<use>嵌入它时,它可以工作.但它不适用于通过嵌入的组内的任何类或ID <use>.

怎么解决?

或者可能有更好的方法吗?

当用户将鼠标悬停在嵌入对象中时,我只需要更改嵌入对象中的这个特定部分,而不是整个组.这是因为该组的不同部分将应用不同的样式,并且当鼠标悬停时它们需要以不同的方式进行更改.

编辑:我想要的

我想要的是一种将一个"库对象"嵌入<defs>到我的SVG文档中的许多不同位置的方法.此对象的某些部分需要使用CSS中的自定义颜色进行样式设置,因为我需要轻松自定义这些颜色而无需更改库对象的代码.

然后,我需要通知用户当鼠标指针是上面这样的"活动"对象通过不同造型的部分:这里有一些明亮的轮廓,显示可点击区域的形状,当鼠标指针超过他们.

不幸的是,我无法将样式应用于<use>元素的子元素,因为它们不是<use>DOM中的子元素(正如其他已经提到的那样).我可以将一些样式应用于该部分内的元素<defs>,因为它们位于DOM中并且可以使用CSS选择器进行寻址,但是它们不能被悬停,因为它们是不可见的,因此将:hover伪类应用于它们是行不通的.如果将这个类应用于它,它也不起作用<use>,因为那时我不能再选择适当的子元素(它们不是子元素<use>).所以我没有任何钩子来应用这些:hover伪类.

也许我的问题还有其他一些解决方案吗?

Tho*_*s W 27

您无法处理通过使用引用的元素.规格说:

对于支持使用CSS进行样式处理的用户代理程序,将引用元素概念性深度克隆到非公开DOM树中,还会复制由引用元素及其内容引起的CSS级联([CSS2],第6章)产生的任何属性值.CSS2选择器可以应用于原始(即引用)元素,因为它们是正式文档结构的一部分.CSS2选择器不能应用于(概念上)克隆的DOM树,因为它的内容不是正式文档结构的一部分.

尽管如此,Firefox还是支持通过使用虫洞来处理"虚拟"元素.所有其他浏览器都没有.

如果您为引用的元素提供填充/描边值,currentColor然后在悬停时更改元素的color属性,那么浏览器支持的更多是更改填充或描边颜色<use>.像这样:

<svg version="1.1" width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <style type="text/css">
    #p0 {fill:currentColor}
    #use1:hover {color:green}
    #use2:hover {color:red}
    #use3:hover {color:blue}
  </style>

  <defs>
    <polygon id="p0" points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" class="active" />
  </defs>

  <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)" id="use1" />
    <use xlink:href="#p0" transform="translate(250,0)" id="use2" />
    <use xlink:href="#p0" transform="translate(460,0)" id="use3" />
  </g>
</svg>
Run Code Online (Sandbox Code Playgroud)

所有主流浏览器(FF,Chrome,IE,Safari)都支持此功能.只有Opera似乎不喜欢它.当然,缺点是这种方法只能改变一种颜色.

因此,如果只是改变颜色,可以使用不同的方法来使用滤镜.例如<feColorMatrix>,使用颜色矩阵可以将一种颜色转换为另一种颜色,如下所示:

<svg version="1.1" width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <style type="text/css">
    #p0 {fill: currentColor}
    #use1:hover {filter: url(#filter1)}
    #use2:hover {filter: url(#filter2)}
    #use3:hover {filter: url(#filter3)}
  </style>

  <defs>
    <g id="p0">
      <polygon points="100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6" fill="red" />
      <rect width="50" height="70" fill="green" />
      <circle cx="-20" cy="-30" r="30" fill="blue" />
    </g>
  </defs>

  <filter id="filter1">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 1 0 0 0 
                     1 0 0 0 0 
                     0 0 1 0 0 
                     0 0 0 1 0" />
  </filter>
  <filter id="filter2">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 0 1 0 0 
                     1 0 0 0 0 
                     0 1 0 0 0 
                     0 0 0 1 0" />
  </filter>
  <filter id="filter3">
    <feColorMatrix type="matrix" in="SourceGraphic" values="0 1 0 0 0 
                     0 0 1 0 0 
                     1 0 0 0 0 
                     0 0 0 1 0" />
  </filter>

  <g transform="translate(70,100)">
    <use xlink:href="#p0" transform="translate(40,0)" id="use1" />
    <use xlink:href="#p0" transform="translate(250,0)" id="use2" />
    <use xlink:href="#p0" transform="translate(460,0)" id="use3" />
  </g>
</svg>
Run Code Online (Sandbox Code Playgroud)

尽管如此,Opera仍然没有运气,而这次我对IE9和Safari也不满意.但我相信它应该可以用Opera和Safari,只有我做了一些不正确的事情.


sva*_*lek 2

这似乎符合规范:

对于支持 CSS 样式的用户代理,将引用元素概念性深度克隆到非公开的 DOM 树中还会复制引用元素及其内容上的 CSS 级联([CSS2],第 6 章)产生的任何属性值。CSS2 选择器可以应用于原始(即引用)元素,因为它们是正式文档结构的一部分。CSS2 选择器不能应用于(概念上)克隆的 DOM 树,因为它的内容不是正式文档结构的一部分。

我尝试了一些使用 use:hover 和/或 [] 属性选择器语法的解决方法,但运气不佳,但可能有解决方案。