【问题标题】:Why doesn't :hover work inside of a <symbol> in SVG? (In Chrome) [duplicate]为什么 :hover 在 SVG 的 <symbol> 内不起作用? (在 Chrome 中)[重复]
【发布时间】:2021-02-14 09:16:47
【问题描述】:

奇怪的是我找不到其他人报告这个问题;这让我觉得也许我做错了什么。

我在包含:hover 伪类的 SVG 中有一个 &lt;style&gt; 标记,当 SVG 直接嵌入 HTML 时它可以正常工作,但是当我将它放在符号中并用 @ 引用它时987654324@标签,&lt;style&gt;标签内的样式不适用。

SVG 直接嵌入:

<svg width="400" height="110">
  <style>
    #myRect:hover {
      fill: red;
    }
  </style>
  <rect id="myRect" width="300" height="100" />
</svg>

在符号中定义,并通过&lt;use&gt; 标签引用。

<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 在 cmets 中提到的,这个问题只存在于 Chrome 中,Firefox 似乎可以正常工作。 (未在任何其他浏览器上测试过)

【问题讨论】:

  • @TemaniAfif 好的,你能给我介绍一些规格吗? 为什么无效?!那么你应该如何在符号中实现悬停效果呢?
  • 制作符号外的样式
  • 这似乎是一个 chrome 错误,Firefox 工作正常。 (或其中之一违反规范)
  • 在第二种情况下,您将鼠标悬停在 use 元素上而不是 myRect 上
  • 为了完整起见,规范:w3.org/TR/SVG2/struct.html#UseStyleInheritance

标签: html css google-chrome svg


【解决方案1】:

这实际上是一个有趣的案例,虽然 Temani Afif 给出了正确的解决方案,但我认为值得在单独的答案中多说几句。

首先,问题不在于&lt;style&gt; 标签的位置。它真的可以在任何地方。真正的问题是由: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 删除了这句话。

关于&lt;use&gt; 元素的样式继承如何工作,现在有很多话要说。但所有这些都涉及一个问题:“如果corresponding element&lt;symbol&gt;)有样式规则,它们如何应用于shadow instance&lt;use&gt; 里面是什么?”

但我确实找不到答案的一个问题是:如果伪类状态适用于shadow host,影子实例元素是否也可以具有该状态? 或者,陈述它更清楚一点:如果指针悬停在 &lt;use&gt; 元素上,它是否也悬停在阴影树内的元素上?

CSS SelectorsCSS Scoping 中没有明显的答案来命名其他两个相关规范。虽然 Temani Afif 提到了第二个(以及 ::shadow was removed 时提出的建议),但这并不相同:没有人试图选择影子树,只是规则选择了相应的元素。

这就是 Firefox 回答“是”而 Chrome 回答“否”的地方。哪一个是错误?有趣的是,我在任何一个错误跟踪器中都找不到错误报告。

【讨论】:

  • 如果指针悬停在 元素上,它是否也悬停在阴影树内的元素上? --> 我会说是的,因为它适用于自定义元素:jsfiddle.net/pq2fLg7n 所以我会投票支持 Chrome 上的错误
  • 我实际上并不知道问题实际上是:hover 伪类,而不是&lt;style&gt; 标签。我会更新问题以反映这一点。谢谢。
  • 问题是它在svg1.1svg2 之间发生了巨大的变化。以前的规则是“CSS2 选择器不能应用于(概念上)克隆的 DOM 树”,现在是“克隆的内容从‘use’元素继承样式并且可以成为用户事件的目标”。
【解决方案2】:

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

【讨论】:

  • 聪明的解决方案+1。但是对于更复杂的样式和动画来说会很不方便。
  • @Arad 我认为您也可以将它用于复杂的样式。我使用了内联样式,但您可以继续使用外部样式(请参阅更新)
猜你喜欢
  • 2017-09-04
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
相关资源
最近更新 更多