为什么.foo a:link,.foo a:visited {}选择器覆盖a:hover,a:active {}选择器在CSS中?

时间:2011-09-10 12:39:26

标签: css css-selectors

示例代码:http://jsfiddle.net/RuQNP/

<!DOCTYPE html>
<html>
<head>
    <title>Foo</title>
    <style type="text/css">
        a:link, a:visited {
            color: blue;
        }

        a:hover, a:active {
            color: red; 
        }

        .foo a:link, .foo a:visited {
            color: green;
        }

        /* A possible fix */
        /*
        .foo a:hover, .foo a:active {
            color: red;
        }
        */
    </style>
</head>
<body>
    <div class="foo">
        <a href="http://example.com/">Example</a>
    </div>
</body>
</html>

我的期望:

链接在悬停时显示为红色。

我得到了什么:

悬停时链接显示为绿色。

问题:

  1. 为什么color.foo a:link, .foo a:visited中定义 选择器覆盖a:hover, a:active中的那个?这是怎么回事?
  2. 我知道我可以通过取消注释来修复它并获得我期望的结果 评论的代码。但是,我想知道如何纠正 .foo a:link, .foo a:visited选择器,使其不会 覆盖color
  3. 中定义的a:hover, a:active

    如果我理解http://www.w3.org/TR/CSS21/cascade.html#specificity(感谢,BoltClock),这是代码中各种选择器的特异性表。

    a:link         - 0 0 1 1
    a:visited      - 0 0 1 1
    a:hover        - 0 0 1 1
    a:active       - 0 0 1 1
    .foo a:link    - 0 0 2 1
    .foo a:visited - 0 0 2 1
    

    因此,当.foo a:link以及a:hover伪类同时应用于类{{A}的A元素时,为link定义的样式会覆盖hover的样式。 1}}。

    同样,当foo以及.foo a:visited伪类同时应用于a:hover类的A元素时,为visited定义的样式会覆盖hover的样式。 1}}。

3 个答案:

答案 0 :(得分:16)

当您第一次使用CSS时,您可能已经了解了指定链接选择器的顺序的LoVe-HAte助记符(a:linka:visiteda:hover,{{ 1}})。你有没有想过为什么选择这个助记符?

嗯,spec中有一条关于当使用所有规则的多个规则适用于同一元素时如何处理链接和动态伪类的注释,这解释了为什么需要在其中设置链接选择器顺序:

  

请注意,A:hover必须放在A:链接和A:访问规则之后,否则级联规则将隐藏A:hover规则的'color'属性。同样,因为A:active放在A:hover之后,当用户激活并悬停在A元素上时,将应用活动颜色(lime)。

无论如何,我想说的是,所有四个伪类,即伪类,具有相同的特异性。其他关于特异性的事情也适用。在这种情况下,在一堆同样特定的选择器中,应用最后一条规则。何时或如何触发每个伪类永远不会相关。

现在,简单介绍a:active选择器会导致您的第二组链接/访问规则覆盖您的第一组链接/访问样式悬停/活动样式,强制在使用.foo选择器添加悬停/活动样式之前,与该类的元素中的链接始终显示为绿色。


很抱歉,如果我的回答看起来很复杂,或者说我的iPhone现在正在我的iPhone上打字,而且很难在这里思考......

答案 1 :(得分:4)

这就是我理解的方式。所有这些伪类具有相同的特异性,因此最后写的伪类获胜。现在伪类:link, :visited, :focus, :hover, :active做了什么?让我们一个接一个地看。

a: link{color: red}告诉用户代理在任何状态中将锚元素着色为红色。运行以下脚本:

  a:link {
  color: red;
  
  }
<a href="www.stackoverflow.com">Go to stackoverflow </a>

锚元素在以下状态中显示为红色当且仅当链接未被访问时

  • 未访问的
  • 悬停
  • 集中(选项卡式)
  • 活性(点击)

因此,a: link{color: red}告诉用户代理在上述所有状态中为锚元素赋予红色。现在让我们将它与a:hover伪类进行比较。运行以下脚本

a:hover {
  color: red;
  
}
<a href="www.stackoverflow.com">Go to stackoverflow </a>

锚元素在以下状态中显示为红色,

  • 悬停
  • 活性(点击)

我们看到:link:hover伪类都能够定义hover状态 - 所以如果你将这两个伪类分配给一个特定元素,那么就会提到一个最后在css文件中获胜。这就是我们说:link覆盖:hover的原因,前者在后面提到。其他伪类也适用相同的概念。我想列出每个伪类的内容。

  

a:link {...}设置未访问链接的以下状态
    - 聚焦(选项卡)
    - 徘徊     - 活跃(点击)

     

link州将覆盖其他所有州。

  

a:visited {...}设置访问链接的以下状态:
    - 聚焦(选项卡)
    - 徘徊     - 活跃(点击)

     

a:visited {...}会覆盖除:link 之外的所有其他状态,当且仅当链接已访问时。

     

请注意,已访问表示必须根据用户代理的缓存将其视为已访问。例如。 10天前访问过的网站可能不在用户代理的缓存中,然后在技术上被视为未访问

  

a:focus {...}为访问和未访问的链接设置以下状态:
    - 聚焦(选项卡)
    - 徘徊     - 活跃(点击)

     

a:focus {...}会覆盖:hover:active个州。

  

a:hover {...}为访问链接和未访问链接设置以下状态:
    - 徘徊     - 活跃(点击)

     

a:hover {...}会覆盖:active

  

a:active {...}为访问和未访问的链接设置以下状态:

     
      
  • 有效(点击)
  •   

答案 2 :(得分:-1)

要解决此问题,请先放置.foo ...选择器,然后将!important添加到其他链接/已访问选择器的颜色值中,如下所示:

    a:link, a:visited {
        color: blue;
    }

    a:hover, a:active {
        color: red !important; 
    }
    .foo a:link, .foo a:visited {
        color: green;
    }

.foo a:link, .foo a:visited选择器覆盖其他选择器的原因,无论您将其置于何处,因为.foo a:linka:link更具体。 (同上:visited。)因此.foo ...选择器将始终覆盖a:link,a:visited选择器,因为它具有父类名称,因此更具体。 (另请阅读@ BoltClock关于LoVe的答案 - HAte - 这是问题的一部分。)