我正在尝试使用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>
我希望它的工作方式是当用户将鼠标指针放在嵌入元素上时,其内部元素的类“active”将改变其样式。当我直接从<defs>
嵌入一个形状并将CSS类应用于嵌入它的<use>
时,它就可以工作。但它不适用于通过<use>
嵌入的组内的任何类或ID。
如何解决?
或许还有更好的方法吗?
当用户将鼠标悬停在嵌入对象中时,我只需更改此特定部分,而不是整个组。这是因为该组的不同部分将应用不同的样式,并且当鼠标悬停时它们需要以不同的方式进行更改。
编辑:我想要的内容
我想要的是将<defs>
中的一个“库对象”嵌入到我的SVG文档中的许多不同位置的方法。这个对象的某些部分需要使用CSS中的自定义颜色进行样式设置,因为我需要轻松自定义这些颜色,而无需更改库对象的代码。
然后,当鼠标指针位于这样的“活动”对象上方时,我需要通过不同的方式设置其部件的方式来向用户发出信号:当鼠标指针悬停在它们上方时,这里和那里显示一些明亮的轮廓以显示可点击区域的形状。
不幸的是,我无法将样式应用于<use>
元素的子元素,因为它们不是DOM中<use>
的子元素(正如其他人已经提到的那样)。我可以将一些样式应用于<defs>
部分内的元素,因为它们位于DOM中,并且可以通过CSS选择器进行寻址,但它们不能悬停,因为它们是不可见,因此将:hover
伪类应用于它们是行不通的。如果将此类应用于<use>
,它也不起作用,因为我无法再选择正确的子元素(它们不是<use>
的子元素)。所以我没有任何钩子来应用那些:hover
伪类。
也许我的问题有其他解决办法吗?
答案 0 :(得分:27)
您无法处理通过使用引用的元素。 The specs说:
对于支持使用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>
所有主流浏览器(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,只有我做了一些不正确的事情。
答案 1 :(得分:2)
这似乎是根据规范:
对于支持使用CSS设置样式的用户代理,概念性很深 将引用的元素克隆到非暴露的DOM树中 复制CSS级联产生的任何属性值([CSS2], 第6章)关于引用的元素及其内容。 CSS2选择器 可以应用于原始(即引用的)元素,因为 它们是正式文件结构的一部分。 CSS2选择器不能 应用于(概念上)克隆的DOM树,因为它的内容 不属于正式文件结构。
我尝试了一些使用的解决方法:hover和/或[]属性选择器语法,运气不好但是可能有解决方案。
答案 2 :(得分:1)
也许这可以提供帮助:https://codepen.io/AmeliaBR/post/customizable-svg-icons-css-variables
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"
class="raw">
<g id="palette">
<path d="M5,90
C5,45 40,-5 75,10
C110,25 80,95 60,95
C50,95 50,75 30,75
C20,75 17,95 12,95
C10,95 5,95 5,90 Z"/>
<g style="fill:currentColor;">
<path d="M30,50
c-10,0 -20,20 -5,15
s15,-15 5,-15z
"/>
<path d="M45,30
c-10,0 -15,15 -5,15
s10,-15 5,-15z
"/>
<path d="M70,20
c-10,0 -20,15 -5,15
s10,-15 5,-15z
"/>
<path d="M75,45
c-10,0 -20,15 -5,15
s15,-15 5,-15z
"/>
<path d="M65,65
c-10,0 -15,25 -5,20
s10,-20 5,-20z"/>
</g>
</g>
</svg>
<svg class="icon-style-A">
<use xlink:href="#palette"/>
</svg>
<svg class="icon-style-B">
<use xlink:href="#palette"/>
</svg>
<svg class="icon-style-C">
<use xlink:href="#palette"/>
</svg>
svg {
display:inline-block;
height:100px;
width:100px;
margin:10px;
border:1px solid;
background:#eee;
}
svg.raw {
/* Default styles for the initial SVG.
* Because they are defined on the <svg>,
* not the individual graphics elements,
* they will NOT be inherited by the <use> references.
*/
fill:rgba(255,250,220,0.4);
stroke: rgba(0,0,0,0.7);
stroke-width:2;
}
svg.icon-style-A {
/* Set the fill, stroke, and color properties to be
inherited by the <use> element:
*/
fill:burlywood;
color:blueviolet;
stroke:#222;
stroke-width:0.5px;
}
svg.icon-style-B {
/* Set the color properties:
*/
fill:blanchedalmond;
color:lavender;
stroke:white;
stroke-width:1px;
/* set some icon styles on the <svg> itself: */
background:aliceblue;
border-radius:20%;
border:none;
box-shadow:royalblue 0 0 2px;
}
svg.icon-style-C {
/* Set the color properties:
*/
fill:beige;
color:green;
stroke:#aaa;
stroke-width:1.5px;
/* icon styles for the <svg> itself: */
background:#222;
border-radius:10%;
border:solid gray;
}
不是很灵活,但它适用于我的项目。