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

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

问题描述

我尝试使用CSS :hover 伪样式来定义从< defs> 嵌入的SVG元素< use> 标签,但它似乎不工作: - /这里是我的代码:

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


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

< defs>
< polygon id =p0points =100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6class =active/>
< g id =gr1>
< polygon id =p1points =130,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6/>
< polygon id =p2points =100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6class =active/>
< / g>
< / defs>

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

< / svg>

< / body>
< / html>

我想让它的工作方式,当用户将鼠标指针放在嵌入的元素,内部元素与类活动将改变其风格。当我从< defs> 直接嵌入一个形状并将CSS类应用到< use> 嵌入它。但它不适用于通过< use> 嵌入的组中的任何类或ID。



修复它?



还是有更好的方法吗?



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



编辑:我想要的



我想得到的是从< defs> 到我的SVG文档中的许多不同的地方。此对象的某些部分需要使用来自CSS的自定义颜色样式,因为我需要轻松地自定义这些颜色,而不更改库对象的代码。



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

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



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

解决方案

您不能解决通过使用引用的元素。 规范说:


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


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



更多浏览器支持更改填充或描边颜色,如果您给参考元素填充/描边值 currentColor ,然后更改< use> 元素的 color 徘徊。像这样:



 < svg version =1.1width =640height =480xmlns =http:// www .w3.org / 2000 / svgxmlns: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 =p0points =100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6class =active/> < / defs> < g transform =translate(70,100)> < use xlink:href =#p0transform =translate(40,0)id =use1/> < use xlink:href =#p0transform =translate(250,0)id =use2/> < use xlink:href =#p0transform =translate(460,0)id =use3/> < / g>< / svg>  



由所有主要浏览器(FF,Chrome,IE,Safari)。只有Opera似乎不喜欢它。缺点是当然,使用此方法只能更改一种颜色。



因此,一个不同的方法可能是使用过滤器,如果它只是改变颜色。例如,使用< feColorMatrix> ,您可以使用颜色矩阵将一种颜色转换为另一种颜色,例如:



 < svg version =1.1width =640height =480xmlns =http://www.w3.org/2000/svgxmlns: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)}& ; < defs> < g id =p0> < polygon points =100,0 50,86.6 -50,86.6 -100,0 -50,-86.6 50,-86.6fill =red/> < rect width =50height =70fill =green/> < circle cx = -  20cy = -  30r =30fill =blue/> < / g> < / defs> < filter id =filter1> < feColorMatrix type =matrixin =SourceGraphicvalues =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 =matrixin =SourceGraphicvalues =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 =matrixin =SourceGraphicvalues =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 =#p0transform =translate(40,0)id =use1/> < use xlink:href =#p0transform =translate(250,0)id =use2/> < use xlink:href =#p0transform =translate(460,0)id =use3/> < / g>< / svg>  



与Opera,虽然,这一次我也不高兴与IE9和Safari。但我相信它应该是可能的歌剧和Safari,只有我做了一些不正确的东西。


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>

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

How to fix it?

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.

Edit: What I want to get

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.

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:

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.

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

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>

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>

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天全站免登陆