译文 | 入门概念:CSS 选择器是如何工作的

作者:Chris Coyier
参考原文地址:Beginner Concepts: How CSS Selectors Work

你刚接触 CSS 吗?这篇文章就是为你准备的!也许理解 CSS 最关键的就是理解「选择器」。选择器可以让你定位到具体的 HTML 元素并且把样式应用于它们之上。不过现在让我们暂时忘掉「样式」,而只是专注于「选择」。

在接下来的例子中,CSS 将会存在于一个被命名为 style.css 的文件中,并且被叫做 index.html 的 HTML 文档所引用。HTML 与 CSS 是分离的,这样能将「设计」与「内容」分离,这也是 CSS 出彩的地方。

HTML 文件看起来会像是这样:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<title>We're learning selectors!</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 id="yay">Yay</h1>
<body>
</html>

CSS 文件则只会包含选择器的代码区块,就像你接下来会看到的一样。

ID 选择器(ID Selector)

1
2
3
#happy-cake {

}
1
2
3
4
5
6
7
8
9
10
11
<!-- WILL match -->
<div id="happy-cake"></div>

<!-- WILL match -->
<aside id="happy-cake"></aside>

<!-- Will NOT match -->
<div id="sad-cake">Wrong ID!</div>

<!-- Will NOT match -->
<div class="happy-cake">That's not an ID!</div>

根据 CSS 选择器优先级(CSS specificity),ID 选择器是优先级最高的选择器类型。这意味着它「打败」了其他的选择器类型和「以胜者姿态」而定义的样式。听起来很棒,但是那也是被诟病的地方,因为在我们需要的时候,使用那些低优先级的选择器会更容易重载值。

类选择器(Class Selector)

1
2
3
.module {

}
1
2
3
4
5
6
7
8
9
10
11
<!-- WILL match -->
<div class="module"></div>

<!-- WILL match -->
<aside class="country module iceland"></aside>

<!-- Will NOT match -->
<div class=".module">The dot is for CSS, not HTML</div>

<!-- Will NOT match -->
<div class="bigmodule">Wrong class</div>

类选择器是你的朋友。它们很可能是这里最有用和最全能的选择器。其一,是因为它们在所有浏览器中都得到了很好的支持;其二,你还可以在 HTML 元素中添加多个「类」(class)(只需要用一个空格分开);其三,你可以用 JavaScript 来明确地的操作类。

元素选择器(Tag Selector)

1
2
3
h2 {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- WILL match -->
<h2>Hi, Mom</h2>

<main>
<div>
<!-- WILL match -->
<h2>Anywhere</h2>
</div>
</main>

<!-- Will NOT match -->
<div class="h2">Wrong tag, can't trick it</div>

<!-- Will NOT match -->
<h2class="yolo">Make sure that tag has a space after it!</h2>

当改变某个独一无二的 HTML 元素的属性时,元素选择器是最有用的,比如在 <ul> 上设置 list-style 或是在 <pre> 上设置 tab-size。同理,在重新设定某个元素的浏览器默认样式时也很有用。

但不要太过于依赖它们。通常来说,写一个类来定义样式可以作用于任何 HTML 元素,这会更有用。

属性选择器(Attribute Selector)

1
2
3
[data-modal="open"] {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- WILL match -->
<div data-modal="open"></div>

<!-- WILL match -->
<aside class='closed' data-modal='open'></aside>

<!-- Will NOT match -->
<div data-modal="false">Wrong value</div>

<!-- Will NOT match -->
<div data-modal>No value</div>

<!-- Will NOT match -->
<div data-modal-open>Wrong attribute</div>

你可能会争论说属性选择器比类选择器更有用,因为它们有一样的优先级但是前者却可以是任何属性(不仅仅是 class),这个属性的值你还可以进行选择。

你说得没错,但是属性选择器 IE6 不支持。

位置选择器(Positional Selectors)

1
2
3
:nth-child(2) {

}
1
2
3
4
5
6
<ul>
<li>nope</li>
<!-- WILL match -->
<li>yep, I'm #2</li>
<li>nope</li>
</ul>

除了 :nth-child,还有几种不同的位置选择器。使用简单的表达式(比如 3n=”every third”),你可以基于它们在 HTML 中的位置来选择元素。你可以在这里测试你的想法或者在这里了解更多的实例

其他的伪选择器(Pseudo Selectors)

1
2
3
:empty {

}
1
2
3
4
5
6
7
8
9
10
11
12
<!-- WILL match -->
<div></div>

<!-- WILL match -->
<aside data-blah><!-- nothin' --></aside>

<!-- Will NOT match -->
<div> </div>

<!-- Will NOT match -->
<div>
</div>

:empty众多伪选择器中的一个,你可以凭借冒号 : 来识别它们。它们通常代表着你不能仅仅通过元素和属性就能定位到的东西。

请注意,它们与用双冒号(::)来识别的伪元素(pseudo elements)有一点不同。伪元素负责借助它们选择的内容来往页面添加东西。

更多提升内容

选择器可以被组合到一起使用。比如:

1
2
3
4
5
6
7
8
9
.module.news {  
/* Selects elements with BOTH of those classes */
}
#site-footer::after {
/* Adds content after an element with that ID */
}
section[data-open] {
/* Selects only section elements if they have this attribute */
}

也有像 ~+> 这样的选择器组合运算子(selector combinators)可以用来对选择器造成影响,就像这样:

1
2
3
4
5
6
7
8
9
.module > h2 {
/* Select h2 elements that are direct children of an element with that class */
}
h2 + p {
/* Select p elements that are directly following an h2 element */
}
li ~ li {
/* Select li elements that are siblings (and following) another li element. */
}

在 CSS-Tricks,这里有一个完整的索引,覆盖了 CSS 中的所有的选择器及其属性。