为啥悬停伪类会覆盖活动伪类

Posted

技术标签:

【中文标题】为啥悬停伪类会覆盖活动伪类【英文标题】:Why does the hover pseudo-class override the active pseudo-class为什么悬停伪类会覆盖活动伪类 【发布时间】:2011-11-22 09:59:07 【问题描述】:

标题基本上说明了一切。

假设我有一个元素,我想在:hover 上更改颜色,但是在单击时,我希望它切换回原来的颜色。所以,我试过这个:

a:link, a:visited, a:active 
    background: red;

a:hover 
    background: green;

事实证明,这是行不通的。经过一番摸索,我意识到:hover 状态正在覆盖:active 状态。这很容易解决:

a:link, a:visited 
    background: green;

a:hover 
    background: red;

a:active 
    background: green;

(我可以将第一条规则与第三条结合起来)。

这是小提琴:http://jsfiddle.net/V5FUy/


我的问题:这是预期的行为吗?据我了解,:active 状态应始终覆盖:hover 状态,因为:active 状态将几乎始终伴随:hover 状态。

【问题讨论】:

这是(不幸的)预期行为。我不知道这种奇怪的起源,但只要我记得,它就一直是这样(现在已经有 10 多年了)。也就是说,我认为它保持这种状态是因为浏览器希望彼此保持一致。所有浏览器都遵循此顺序这一事实意味着您编写的代码将适用于所有浏览器。不过,我不同意您的评估,即 :active 应始终覆盖 :hover。 @Brendan - 谢谢。你似乎是这里唯一理解我的问题的人。 也许这与添加 :active:hover 的顺序有关(分别添加到 CSS1 和 CSS2 中)......我们现在似乎处于历史领域,而不是编程。 @JosephSilber 我认为令人困惑的是您认为 :hover 和 :active 是互斥的。实际上,当您悬停时,活动的锚链接具有两个伪类。所以它被第一行设置样式并在之后立即被覆盖。这是一个使用显式类的示例link 这是我在外出时用 iPhone 回答的一个相关问题:***.com/questions/7371732/… 【参考方案1】:

是的,这是预期的行为,

让我们看另一个例子。只需添加两个类,

<ul>
<li class="item first">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item last">item</li>
</ul>

这里的 class first 也与 class item 一起出现。 但是如果我们以错误的顺序声明我们的 CSS,就不会给出想要的行为

.first  background: blue; 
.item  background: red; 

如您所见,将使用最后一个匹配的选择器。 它和你的例子一样,没有什么更符合逻辑的, 2 个伪类被认为是相等的,因此适用相同的规则 最后匹配的防守获胜。

编辑

伪类是平等的,它是最后定义的赢家!这是一个 jsFiddle,它证明了我的观点 :link 在 :hover 之后定义,:link 获胜 (test) 所以,你的 :hover 覆盖 :link 的声明是错误的,它和 :active 一样,都是关于订单的.

【讨论】:

你们似乎都忽略了这一点。你们都明白:hover 总是覆盖:link,即使当你悬停时它仍然是一个链接。因为每个人都明白,如果您将样式应用于:hover 状态,则您对原始状态不感兴趣。同样的逻辑应该适用于:active 状态... 正如我所说,伪类是平等的,它是最后定义的赢家!这是一个 jsFiddle,它证明了我的观点 :hover 之后定义的 :link:link 获胜(jsfiddle.net/kVLEZ)所以,你的 :hover 覆盖 :link 的声明是错误的,它就像 :active ,都是关于订单的。 对于那些难以记住样式表中与a 标记相关的伪类的正确顺序的人来说是 - LoVe 在 HAte 之前。 Link -> Visited -> Hover -> Active【参考方案2】:

必须在悬停状态之后声明活动状态,在您的 CSS 中,您将活动状态聚集在一起活动状态之前,因此它不会被触发。

如果你说明它工作的正确顺序,如下所示,它工作正常。

a.noworks:link, a.noworks:visited 
    background: red;


a.noworks:hover 
    background: green;


a.noworks:active 
    background: red;

所以,回答你的问题,是的,这是预期的行为。

以下是操作顺序:

a:link
a:visited
a:hover
a:active

【讨论】:

你们似乎都忽略了这一点。你们都明白:hover 总是覆盖:link,即使当你悬停时它仍然是一个链接。因为每个人都明白,如果您将样式应用于:hover 状态,您对原始状态不感兴趣。同样的逻辑应该适用于:active 状态... 链接遵循操作顺序,不能乱序覆盖。必须满足预定义的条件才能使操作顺序起作用。 1. 是链接吗?如果是,请应用所述颜色。 2. 去过吗?如果是,则应用所述颜色。 3. 链接是否被悬停?涂上所说的颜色。 4. 链接是否被点击(激活)?如果是,请应用所述颜色。你不能打破这个顺序,否则它会使整个链接样式过程变得毫无意义。这就像开车没有先启动它。【参考方案3】:

因为在定义:active 之后的第一个代码中定义了:hover,所以:hover“覆盖”了:active。第二种情况正好相反,:active 覆盖:hover

【讨论】:

你们似乎都忽略了这一点。你们都明白:hover 总是覆盖:link,即使当你悬停时它仍然是一个链接。因为每个人都明白,如果您将样式应用于:hover 状态,您对原始状态不感兴趣。同样的逻辑应该适用于:active 状态... 你没有抓住重点。由于您首先定义了:link,因此:hover 会覆盖它。如果你把:hover放在前面,那就不行了。【参考方案4】:

编辑:

对不起,我误解了这个问题。

基本上,当您处于活动状态(使用鼠标指针)时,您实际上也处于悬停状态。因此,根据 CSS 规则,它会读取样式表中的最后一条。

当您将鼠标悬停在链接上并按住鼠标键时,如果我们将伪类作为普通类:

<a class="active hover"></a>

如果你的 CSS 是

.activecolor:green
.hovercolor:red

它会应用红色

但是如果你的 CSS 是

.hovercolor:red
.activecolor:green

它会应用绿色

来自W3C

a:link     color: red     /* unvisited links */
a:visited  color: blue    /* visited links   */
a:hover    color: yellow  /* user hovers     */
a:active   color: lime    /* active links    */

注意 A:hover 必须放在 A:link 和 A:visited 之后 规则,否则级联规则将隐藏“颜色” A:hover 规则的属性。同样,因为 A:active 被放置 A:hover 之后,当用户同时使用活动颜色(石灰) 激活并悬停在 A 元素上。

【讨论】:

你仍然没有抓住重点。阅读问题的最后一行! 你又一次错过了重点。我知道在处于:active 状态时,我也处于:hover 状态。我已经在我的问题中明确说明了这一点。我试图理解的是:为什么这两个伪类具有相同的特异性权重?在我看来,:active 应该总是覆盖 :hover 正是因为你总是 :hover 而成为 :active!!!! 你们似乎都忽略了这一点。你们都知道:hover 总是覆盖:link,即使当你悬停时它仍然是一个链接。因为每个人都明白,如果您将样式应用于:hover 状态,您对原始状态不感兴趣。同样的逻辑应该适用于:active 状态...【参考方案5】:

这就是它的工作原理,我将尝试解释原因。正如我们所知,CSS 会在应用样式时继续搜索文档并应用最特定于元素的样式。

例子:

li.betterList  better list styling here 

更具体,会覆盖

li  list styling here 

这些 Puesdo 选择器都被认为具有相同的特异性,因此最后一行将覆盖前一行。 W3Schools上的注释证实了这一点

注意: :active 必须在 CSS 定义中的 :hover(如果存在)之后才能生效!

你也可以把这个 CSS 放在你的 jsfidle 上,然后看着它被覆盖,因为它们具有相同的特性

.works background: red
.works background: green

【讨论】:

【参考方案6】:

这是预期的行为,因为大多数人总是将:hover 伪类放在规则组的末尾。

声明顺序对伪类很重要(在此处查看更多信息:http://reference.sitepoint.com/css/pseudoclasses),因此最终规则优先,与 CSS 中的其他规则一样。

对于大多数人来说,我认为期望的行为:

a:link 
  ⋮ declarations

a:visited 
  ⋮ declarations

a:hover 
  ⋮ declarations

由于:active 不是那么有用,它被忽略...或与a:linka:visited 组合...然后被a:hover 覆盖

W3C 在这里详细说明:

注意 A:hover 必须放在 A:link 和 A:visited 之后 规则,否则级联规则将隐藏“颜色” A:hover 规则的属性。同样,因为 A:active 被放置 A:hover 之后,当用户同时使用活动颜色(石灰) 激活并悬停在 A 元素上。

http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes

即使是 W3schools 也能做到这一点:

注意:a:hover 必须在 CSS 中的 a:link 和 a:visited 之后 定义才能有效!!

注意:a:active 必须在 CSS 定义中按顺序出现在 a:hover 之后 要有效!!

http://www.w3schools.com/css/css_pseudo_classes.asp

【讨论】:

【参考方案7】:

我认为您至少应该考虑链接(或按钮)上的用户交互流程

通常,

    :link一直是默认的(未改动), 然后,当用户指向按钮时,:hover 就会发挥作用。 一旦用户指向链接或按钮,他/她就会点击,这就是:active 的作用。

这是我们如何与链接(或按钮)交互的标准顺序。 :visited 除外,其结果仅在用户之前按下链接时才明显。

如果您在处理链接时牢记助记符:' L o V e HA te ',这将非常有帮助 (:visited 除外,它不适用于按钮)。

但是,如果您真的想要进行覆盖,例如,您想要更改已在活动状态下访问过的链接的颜色,您可以执行以下操作:

a:visited:active 
     color: red;   

但最重要的是,如果没有必要,请避免更改标准顺序。

【讨论】:

【参考方案8】:

您可以使用 :not() 选择器让 :active 伪类覆盖 :hover 伪类,而不管声明的顺序如何。

a:link, a:visited, a:active 
    background: red;


a:hover:not(:active) 
    background: green;

这样,:hover 选择器只有在 :active 选择器没有被触发时才会被触发。

【讨论】:

以上是关于为啥悬停伪类会覆盖活动伪类的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 覆盖 nth-child 伪类

如何使用 firebug 检查 CSS 伪类?

如何使用 firebug 检查 CSS 伪类?

为啥用css中伪类hover实现(鼠标悬停显示文字,鼠标移走文字消失)的效果失败(脚本没有错)?

css鼠标悬停伪类

伪类选择器