15

谁能告诉我是否有任何理由在我的样式表中使用a {}代替(或相邻) ?a:link, a:visited {}我在浏览器、网站等方面对此进行了不一致的测试,所以我从来没有给出令人满意的答案。我也无法在 Google 上找到答案。

这当然是假设永远不会有理由使用没有值的<a>标签。href也许这是一个错误的假设。

**编辑**

我知道这些选择器的作用。我正在寻找为什么我会使用a而不是a:linkor的原因a:visited,因为a它总是有一个href属性。但正如 Chris Blake 和 Ryan P 在答案中所说,还有<a name="top">javascript 用法,它们都不需要该href属性。

4

5 回答 5

22

这当然是假设永远不会有理由使用没有值的<a>标签。href也许这是一个错误的假设。

这取决于您的项目。严格来说,这一个错误的假设,因为并非每个<a>元素都需要有一个href属性。事实上,在 HTML5 中仍然不需要href为每个<a>. Chris BlakeRyan P提到了命名锚点,我要补充一点,虽然 for 的name属性在 HTML5<a>中已经过时,但命名锚点仍然很普遍,并且将继续存在,仅仅是由于传统和传统。

也就是说,今后,建议作者使用id属性而不是命名锚来指定文档锚片段。

此外,<a>缺少href属性但具有onclickJavaScript 属性的元素是一团糟。即使您坚持使用onclick绑定事件,为了优雅降级,您至少应该使用href.

但是为了简单起见,让我们假设您不会编写没有属性的<a>元素。href

考虑到这一点,回到 CSS 选择器,有两点需要考虑:

他们是一样的吗?

不,选择器aa:link, a:visited不是严格等价的。我将引用我之前关于这个主题的答案:

选择器a应该匹配任何<a>元素,而a:link只匹配未访问的超链接<a>的元素(HTML 4 文档类型将超链接定义为具有属性的元素)。它在任何一个规范中都没有说明应该自动转换为,反之亦然。<a>hrefaa:link

换句话说,在 HTML 中,a:link, a:visited(在 CSS1 中)严格等同于a[href](在带有属性选择器的 CSS2 中)或a:any-link(在选择器级别 4中的新),而不是a. 请注意,属性是否具有值并不重要,只要它存在,伪类就会匹配,因此[href]. 另请注意,这适用于所有当前的 HTML 标准,我相信这包括 HTML5,因为如上所述href不是任何现有规范中的必需属性。

请记住,其他语言可能为:linkand定义完全不同的语义:visited——碰巧它们与 HTML 中同样特定的选择器相吻合,接下来将介绍...

特异性

这是一个巨大的陷阱:aa:linkor更不具体a:visited,这是一个非常常见的特异性问题来源,在将样式应用于a,a:linka:visited单独应用时尤其明显。然后,这会导致各种!important黑客攻击来解决对特异性缺乏了解的问题。

例如,考虑这个 CSS:

/* All unvisited links should be red */
a:link {
    color: red;
}

/* All visited links should be slightly darker */
a:visited {
    color: maroon;
}

/* But no matter what, header links must be white at all times! */
body > header > a {
    color: white;
}

这不能按预期工作,因为a:linkand a:visited(我称之为通用规则/选择器)比body > header > a(我称之为专用规则/选择器)更具体,因此标题链接实际上永远不会是白色的:

/* 1 pseudo-class, 1 type  -> specificity = (0,1,1) */
a:link, a:visited

/* 3 types                 -> specificity = (0,0,3) */
body > header > a

现在大多数 CSS 编码人员首先想到的就是投入!important,完全胜过特异性:

body > header > a {
    color: white !important;
}

但这会让你得到各种各样的坏名声,对吧?所以我们不要那样做。

选择器级别 4 为您提供的不是一个,而是两个解决此特异性问题的方法。这些解决方案虽然是新的,但在 Internet Explorer 和 Microsoft Edge Legacy(UWP/EdgeHTML/not-Chromium 之一)中不受支持,但值得庆幸的是,在 Internet Explorer 7 及更高版本中还有第三种解决方案,a[href]即我上面提到的属性选择器。

1.:any-link伪类

:any-link它背后有一些历史,您可以在我对这个问题的回答中阅读,但实际上,:any-link它可以作为:link, :visited. 它的主要目的是消除选择器重复,因此实际上存在:is(:link, :visited).

您可以a:any-link在您的专门规则中使用来匹配通用规则a:linka:visited规则的特殊性,从而允许它覆盖它们:

a:link {
    color: red;
}

a:visited {
    color: maroon;
}

/* 1 pseudo-class, 3 types -> specificity = (0,1,3) */
body > header > a:any-link {
    color: white;
}

2.:where()伪类

:where()它背后也有一些历史,但本质上它是一个类似物,:is()除了它将其论点的特殊性归零。有关它如何工作的深入指南,请参阅我对这个问题的回答。

:link您可以将 s和:visited伪类包装在:where()s 中以删除它们的伪类特异性,从而允许它们被专用规则覆盖:

/* 1 type                  -> specificity = (0,0,1) */
a:where(:link) {
    color: red;
}

/* 1 type                  -> specificity = (0,0,1) */
a:where(:visited) {
    color: maroon;
}

/* 3 types                 -> specificity = (0,0,3) */
body > header > a {
    color: white;
}

3. a[href](对于旧版浏览器)

幸运的是,如果您需要支持较旧的浏览器,属性选择器与伪类一样具体。这意味着您可以使用a[href]来表示 both/eithera:link和/or a:visited,而不会遇到具体问题,因为它们同样具体!

/* 1 attribute, 3 types    -> specificity = (0,1,3) */
body > header > a[href] {
    color: white;
}

那么使用哪个选择器呢?

这仍然是非常主观的,但我遵循以下个人经验法则:

  • 适用于不依赖于链接状态的a样式(即只要是链接就可以)。

  • 应用于a:link和是否访问链接无关紧要a:visited的样式。

  • 考虑到上面提到的特殊性问题,不要在 and / 规则之间混用 a任何a:link声明a:visited。如果我需要将相同的属性应用于某处的两个州,但我已经在单独a:linka:visited规则中拥有它,我将使用上述 3 个选项之一来避免特异性问题。

例如,以下是我在网站发布前的 Coming Soon 页面中使用的链接样式:

a {
    text-decoration: none;
    transition: text-shadow 0.15s linear;
}

a:link {
    color: rgb(119, 255, 221);
}

a:visited {
    color: rgb(68, 204, 170);
}

a:hover, a:active {
    text-shadow: 0 0 0.5em currentColor;
}

a:focus {
    outline: thin dotted;
}

/* ... */

footer a:link, footer a:visited {
    color: rgb(71, 173, 153);
}

text-shadow过渡是为所有元素定义的,a无论它们是否被访问,因为过渡只有在其中一个被鼠标悬停并单击时才会生效(对应于a:hover, a:active规则)。

现在,我希望访问过的链接比未访问过的链接有更深的阴影,所以我将颜色放在单独的a:link规则a:visited中。但是,出于某种原因,无论是否访问页脚链接,我都希望页脚链接显示相同的颜色。

如果我使用footer a,我会遇到上面描述的特异性问题,所以我选择footer a:link, footer a:visited了。这是出于遗留原因(如下所示,我最初是在 2012 年发布的!),但当然可以将其缩短为footer a:any-link. 然而,特异性匹配原则同样适用。

希望我的建议可以帮助您处理链接样式的混乱。

于 2012-05-14T19:29:38.490 回答
3

和用于分别为普通链接a:link和访问链接a:visited指定自定义(浏览器默认除外)颜色,而a {}用于覆盖所有样式,包括a:link, a:visited, a:active. 例如,无论链接是否处于活动状态、是否访问过或悬停在上面,以下内容都将具有相同的颜色:

a { color:red; }

您可以通过使用单独的样式(例如a:pseudoClass符号)来避免这种情况。

于 2012-05-14T16:24:46.463 回答
3

那么你可以有一个只是一个锚的锚。例如,

<a href="#top">Return to top</a>

<a name="top">Top</a>

这纠正了您的错误假设(尽管“顶部”不需要锚点,但它在哲学上是最正确的)。

此外,正如 Sarfraz 所说,如果样式化(并假设在其他声明之后) ,则会a {}覆盖所有出现的其他样式属性。a:a {}a:

于 2012-05-14T16:25:12.187 回答
3

a:link并且a:visited有特定的含义。a它本身会影响所有<a>元素,而a:link只会影响尚未访问的a:visited链接,并且只会影响已访问的链接。

于 2012-05-14T16:25:17.150 回答
3

有两种情况,ana可能没有href属性。第一个是常规锚点(即<a name="someplace" />),第二个是纯 Javascript 交互(即<a onclick="doSomething( );" />)。这些不是“链接”,不应使用相同的样式。

编辑:澄清一下,a:link几乎等同于a[href](我相信前一个符号在属性选择器可用或标准化之前就存在)。因此,如果您希望所有锚标签的样式都相同,则使用anot的原因是。a:link某些浏览器中的默认样式以不同的方式显示这两种 - 例如下划线仅适用于a:link而不适用于a.

于 2012-05-14T16:25:45.987 回答