css - SVG 使用元素和 :hover style

标签 css svg hover styling

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

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

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

如何解决?

或者也许有更好的方法?

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

编辑:我想要得到什么

我想得到的是一种从 <defs> 嵌入一个“库对象”的方法放入我的 SVG 文档中的许多不同位置。该对象的某些部分需要使用 CSS 中的自定义颜色设置样式,因为我需要在不更改库对象代码的情况下轻松自定义这些颜色。

然后,当鼠标指针位于此类“事件”对象上方时,我需要通过不同的样式来向用户发出信号:这里和那里有一些明亮的轮廓,以在鼠标指针悬停在可点击区域上方时显示可点击区域的形状。

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

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

最佳答案

您不能寻址通过使用引用的元素。 The specs说:

For user agents that support Styling with CSS, the conceptual deep cloning of the referenced element into a non-exposed DOM tree also copies any property values resulting from the CSS cascade ([CSS2], chapter 6) on the referenced element and its contents. CSS2 selectors can be applied to the original (i.e., referenced) elements because they are part of the formal document structure. CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree because its contents are not part of the formal document structure.

不过,Firefox 支持寻址通过使用虫洞包含的“虚拟”元素。所有其他浏览器都没有。

如果您为引用的元素提供 currentColor 的填充/描边值,浏览器还支持更改填充或描边颜色。然后你改变 color <use> 的属性(property)元素悬停。像这样:

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

所有主流浏览器(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>

不过,Opera 仍然不走运,这次我对 IE9 和 Safari 也不满意。但我相信 Opera 和 Safari 应该是可能的,只是我做了一些不是 100% 正确的事情。

关于css - SVG 使用元素和 :hover style,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13673441/

相关文章:

jQuery 调整 CSS 元素的大小

html - 控制 Facebook Like 按钮的水平定位

html - border-radius 的圆 Angular 只影响一侧

javascript - Fabric.js 路径数组有大小限制吗?

javascript - 如何使用 svg 中的标记为改变路径长度(线)设置动画

html - 悬停CSS以显示隐藏文本

javascript - 使 slider 响应(jQuery)

html - 带表格的文本溢出省略号

css - 使用 Twitter Bootstrap 字形图标切换类

html - 悬停CSS时闪烁的颜色