问题描述
奇怪的是我找不到其他人报告此问题;这让我觉得也许我做错了。
我在包含<style>
伪类的SVG中有一个:hover
标记,当SVG直接嵌入HTML时,但是当我将其放在符号和引用中时,它可以正常工作带有<use>
标签的标签,则不会应用<style>
标签内的样式。
SVG直接嵌入:
<svg width="400" height="110">
<style>
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</svg>
以符号定义,并通过<use>
标记进行引用。
<svg style="display: none">
<symbol id="rectangle">
<style>
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
为什么会这样?似乎是一种怪异的行为,我错过了什么吗?!
更新:正如注释中提到的Temani Afif一样,此问题仅存在于Chrome中,Firefox似乎可以正常工作。 (尚未在其他任何浏览器上进行测试)
解决方法
这实际上是一个有趣的案例,尽管Temani Afif提供了正确的解决方案,但我认为在一个单独的答案中再说几句话是值得的。
首先,问题不在于<style>
标签所在的位置。它可能真的在任何地方。真正的问题是由:hover
选择器提出的。
<svg style="display: none">
<symbol id="rectangle">
<style>
#myRect {
fill: blue;
}
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
先前的SVG 1.1 spec有一小段文字说“ CSS2选择器不能应用于(从概念上来说)克隆的DOM树”,但是SVG 2 spec删除了该句子。
关于<use>
元素的样式继承如何工作,现在有很多话要说。但所有这些都涉及一个问题:“如果corresponding element(<symbol>
有样式规则,如何将它们应用于shadow instance({{1}内部是什么) })?”
但是我确实找不到答案的一个问题是:如果伪类状态适用于shadow host,那么影子实例元素也可以具有该状态吗?声明得更清楚:如果指针悬停在<use>
元素上,它是否也悬停在阴影树内的元素上?
CSS Selectors或CSS Scoping中没有明显的答案来命名其他两个相关规范。尽管Temani Afif提到了第二个(以及::shadow was removed时提出的内容),但这并不相同:没有人尝试选择阴影树,只是规则选择了一个相应的元素。>
那是Firefox回答“是”而Chrome回答“否”的地方。错误是哪一个?有趣的是,我在两个错误跟踪器中都找不到错误报告。
,使用CSS变量的另一种选择可以继承继承性的阴影:
use[href*="rectangle"]:hover {
--f:red;
}
<svg style="display: none">
<symbol id="rectangle">
<rect style="fill:var(--f)" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
没有内联样式的作品:
use[href*="rectangle"]:hover {
--f:red;
}
<svg style="display: none">
<symbol id="rectangle">
<style>
rect {
fill:var(--f);
}
</style>
<rect width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>