SVG USE 元素和 :hover 样式 [英] SVG USE element and :hover style

查看:17
本文介绍了SVG USE 元素和 :hover 样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use CSS :hover pseudoclass to style SVG elements embeded from <defs> by <use> tag, but it doesn't seem to work :-/ Here's my code:

<!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"将改变其样式.当我直接从 嵌入一个形状并将 CSS 类应用到嵌入它的 时,它会起作用.但它不适用于通过 嵌入的组内的任何类或 ID.

I want it to work in a way that when user places the mouse pointer over the embedded element, its inner element with class "active" will change its style. It works when I embed one shape from the <defs> directly and apply the CSS class to the <use> which embeds it. But it doesn't work for any classes or ID's inside the group embedded through <use>.

如何解决?

或者也许有更好的方法来做到这一点?

Or maybe there's a better way to do it?

当用户将鼠标悬停在嵌入对象内时,我只需要更改该特定部分,而不是整个组.因为这个组的不同部分会应用不同的样式,鼠标悬停时需要改变不同的样式.

I need to change only this particular part inside the embedded object when the user hovers it, not the whole group. It's because different parts of this group would have different styles applied, and they need to change differently when hovered by the mouse.

我想要的

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

What I want to get is a way to embed one "library object" from <defs> into many different places in my SVG document. Some parts of this object need to be styled with custom colors from the CSS, because I need easy customization of those colors without changing the library object's code.

然后当鼠标指针位于这种活动"对象上方时,我需要通过对其部分进行不同的样式设置来向用户发出信号:一些明亮的轮廓在这里和那里显示当鼠标指针位于可点击区域上方时的形状.

And then I need to signal the user when the mouse pointer is above such "active" object by styling its parts differently: some bright outlines here and there to show the shape of the clickable areas when the mouse pointer is over them.

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

Unfortunately, I cannot apply the style to the <use> element's subelements, because they're not subelements of <use> in the DOM (as others already mentioned). I can apply some styles to the elements inside the <defs> section, because they're in the DOM and they're addressable with CSS selectors, but they cannot be hovered, because they're invisible, so applying :hover pseudoclass to them doesn't work. And it doesn't work either if this class is applied to the <use>, because then I cannot sub-select the proper sub elements (they're not sub-elements of <use>). So I don't have any hook to apply those :hover pseudoclass to.

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

Maybe there's some other solution to my problem?

推荐答案

您无法解决通过使用引用的元素.规范说:

You can not address an element that is referenced via use. The specs say:

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

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 支持处理通过使用虫洞包含的虚拟"元素.所有其他浏览器都没有.

Nevertheless, Firefox supports addressing "virtual" elements the are included via a use wormhole. All other browsers don't.

如果你给被引用的元素一个 currentColor 的填充/描边值,然后你更改元素的 color 属性,那么浏览器还支持更改填充或描边颜色. 元素悬停.像这样:

What more browser do support is changing filling or stroking color if you give the referenced element a fill/stroke value of currentColor and then you change the color property of the <use> element on hover. Like so:

<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 似乎不喜欢它.缺点当然是,这种方法只能改变一种颜色.

This is supported by all major browsers (FF, Chrome, IE, Safari). Only Opera doesn't seem to like it. The disadvantage is of course, with this method you can only change one color.

因此,如果只是改变颜色,则可能使用过滤器的另一种方法.例如,使用 ,您可以使用颜色矩阵将一种颜色转换为另一种颜色,如下所示:

So, a different method would possible be to use filters, if it's only about changing color. For example using <feColorMatrix>, you can transform one color to another using a color matrix, like this:

<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% 正确地做一些事情.

Still no luck with Opera, though, and this time I wasn't happy with IE9 and Safari either. But I believe it should be possible with Opera and Safari, only I did something not 100% correctly.

这篇关于SVG USE 元素和 :hover 样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆