【问题标题】:Why is hover for input triggered on corresponding label in CSS?为什么在CSS中的相应标签上触发输入悬停?
【发布时间】:2012-02-24 07:06:11
【问题描述】:

我是否遗漏了什么,或者这个例子的行为——http://dabblet.com/result/gist/1716833——在 Webkits/Fx 中相当奇怪?

有一个带有标签和以下选择器的输入:

input:hover + .target {
    background: red;
}

当您悬停附加到inputlabel 时会触发此样式,而不仅仅是input 本身。更重要的是:labelforinput 包裹在 label 之间是有区别的——如果你首先悬停input,然后将光标直接移动到.target——奇怪的悬停不会在包装版本中触发。

这只是在 Firefox 和 Safari/Chrome 中重现,但在 Opera 中没问题。

所以,问题是:这个问题是否在规范中的某处有所描述?我找不到任何合适的地方来描述它并说明什么行为是正确的。

【问题讨论】:

  • 根据w3.org/TR/html4/interact/forms.html#h-17.9,“当 LABEL 元素获得焦点时,它会将焦点传递给其关联的控件。”
  • 是的,但是 HTML 中的 focus 是一回事,CSS 中的伪类是另一回事,这些领域之间不可能有任何相似之处。类似的情况在 CSS4 中被描述为草稿:dev.w3.org/csswg/selectors4/#idref-combinators — 但我不认为,这必须像现在在 Fx 和 webkits 中那样工作。
  • @kizu::focus 也是一个 CSS 伪类。你说得对,标签焦点与这里的问题无关,但这只是我想指出的。

标签: html css firefox css-selectors webkit


【解决方案1】:

这在 HTML 规范中;直到October 2012 WD 才被添加到 W3C HTML5(强调我的):

:hover 伪类被定义为匹配一个元素,“而用户指定一个带有指针设备的元素”。仅出于定义:hover 伪类的目的,HTML 用户代理必须将一个元素视为用户指定的元素,如果它是:

  • 用户使用指点设备指示的元素。

  • 具有用户使用指针设备指示的后代的元素。

  • 一个元素,它是当前匹配 :hover 的 label 元素的标记控件。

living spec 中出现相同的文本。


几年前,我在我的网站联系表单的先前设计中发现了这种行为,其中label:hover 也会在任何表单输入元素上触发:hover,该元素要么是其后代,要么由其for 属性引用。

此行为实际上是在this bug reportthis (rather short) mailing list thread 中添加到最近构建的Gecko(Firefox 的布局引擎)中,并在WebKit many years back 中实现。正如您所注意到的,该行为不会在 Opera 中重现。看起来 Opera Software 和微软没有收到这份备忘录。

我可以在规范中找到可能与此行为相关的所有内容是here,但我不确定(我用斜体注释):

  • :hover 伪类适用于用户使用指针设备指定一个元素,但不一定激活它。例如,当光标(鼠标指针)悬停在元素生成的框上时,可视用户代理可以应用此伪类。

[...]

选择器没有定义“:active”或“:hover”元素的父元素是否也处于该状态。 [它似乎也没有为元素的子元素定义相同的内容。]

注意:如果 ':hover' 状态适用于一个元素,因为它的子元素是由一个指针设备指定的,那么 ':hover' 可能适用于一个元素不在指点设备下方。

但我可以得出的结论是,这种行为至少在 Gecko 和 WebKit 中是设计使然。


关于你在这里所说的:

更重要的是:labelforinput 之间存在差异,包裹在 label 中 — 如果您首先将鼠标悬停在 input 上,然后将光标直接移动到 @ 987654344@ — 奇怪的悬停不会在包装版本中触发。

鉴于上述行为,这里剩下的唯一可能就是你只是被级联咬了。

基本上,这条规则:

/* 1 type, 1 pseudo-class, 1 class -> specificity = (0, 2, 1) */
input:hover + .target {
    background: red;
}

比这条规则更具体:

/* 1 class, 1 pseudo-class         -> specificity = (0, 2, 0) */
.target:hover {
    background: lime;
}

因此,在适用的浏览器中,第一个复选框旁的 label.target 在悬停时将始终为红色,因为更具体的规则始终优先。第二个复选框后跟一个span.target,因此这些行为都不适用;光标在span.target上时,只有第二条规则生效。

【讨论】:

  • «因此,在适用的浏览器中,label.target 在悬停时将始终为红色,因为更具体的规则始终优先» — 有一件事。转到示例,到第二个块,将复选框悬停,然后直接向右移动:当您将悬停.target 时,它将是石灰!但是,邮件列表和错误的链接非常好!在简历中:规范中没有这种行为的迹象,这只是浏览器的决定。遗憾的是,他们在 w3 中没有草稿将其“合法化”。
  • @kizu:这是因为在您的第二个区块中,它是span.target,而不是label.target。我编辑了我的答案来解释这一点。至于规范……也许有一天我会纠缠 CSS 工作组。
  • 我明白了,我想知道这种行为:youtube.com/watch?v=R94O9H1sZBY — 为什么块从输入悬停后变成绿色,但不是直接?由于特殊性,它必须始终是红色的,但仍然是红色的。
  • @kizu:哦……我不知道。即使我在 Firebug 中查看它(启用 :hover 样式),它似乎也没有一致地应用样式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多