CSS 基于文档结构的选择器
1. 元素关系
基于文档结构的选择器主要依赖于几个基本的概念: 父子关系
, 祖先后代的关系
, 兄弟关系
。
HTML 文档是一个结构化的, 所有定义在HTML文档中的元素构成一棵"树".
比如,我们有如下一个 HTML 文档:
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Meerkat Central</title>
</head>
<body>
<h1>Meerkat <em>Central</em></h1>
<p>
Welcome to Meerkat <em>Central</em>, the <strong>best meerkat web site
on <a href="inet.html">the <em>entire</em> Internet</a></strong>!</p>
<ul>
<li>We offer:
<ul>
<li><strong>Detailed information</strong> on how to adopt a meerkat</li>
<li>Tips for living with a meerkat</li>
<li><em>Fun</em> things to do with a meerkat, including:
<ol>
<li>Playing fetch</li>
<li>Digging for food</li>
<li>Hide and seek</li>
</ol>
</li>
</ul>
</li>
<li>...and so much more!</li>
</ul>
<p>
Questions? <a href="mailto:suricate@meerkat.web">Contact us!</a>
</p>
</body>
</html>
1.1 父子关系
在 HTML 这颗树中,如果一个元素恰好位于另一个元素的上一级或下一级,则这些元素具有父子关系
。
比如:
- 左起第一个 p 就是 em 和 strong 的父, 而 em 和 strong 便是 p 的子。 它们之间是父子关系。
- 这里的 strong 又是 a 的父, a 是 strong 的子。 它们之间是父子关系。
1.2 祖先后代的关系
如果从一个元素到另一个元素的路径经过两层或多层级,则这些元素之间存在祖先后代关系,但不具有父子关系。
但是: 子元素也是后代,父元素也是祖先。
比如:
- 最右上侧的 ul 元素是两个 li 元素的父,同时他也是所有它的子元素 li 的子或者后裔的祖先。
- html 元素是所有元素的祖先。
1.2 兄弟关系
同一个父元素的同级子元素之间是兄弟关系。
比如:
- 最下方的 ol 元素有 三个子元素 li, 这三个 li 元素之间就是兄弟关系。
2. 后代选择器
比如, 你想匹配所有嵌套在 h1 元素中的 em 元素, 你可以这样写:
h1 em {color: gray;}
这个规则只会将嵌套在 h1 元素中的 em 元素的文字编程灰色,对于其他的 em 元素,比如嵌套在 p 中的 em 都不会起作用。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Simple styling of a simple document</title>
<style type="text/css">
html { background-color: white; }
h1 em {color: gray;}
</style>
</head>
<body>
<h1>Hello <em>World!</em></h1>
<h2>My css <em>example</em></h2>
</body>
</html>
这里的语法规则是: 使用多个空格将一个或多个选择器组合起来。
比如:
ul ol ul em {color: gray;}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Simple styling of a simple document</title>
<style type="text/css">
html { background-color: white; }
ul ol ul em {color: gray;}
</style>
</head>
<body>
<ul>
<li>It's a list</li>
<li>A right smart list
<ol>
<li>Within, another list
<ul>
<li>This is <em>deep</em></li>
<li>So <em>very</em> deep</li>
</ul>
</li>
<li>A list of lists to see</li>
</ol>
</li>
<li>And all the lists for me!</li>
</ul>
</body>
</html>
3. 孩子选择器
有些时候,你不想匹配到任意的后代的节点,而是想精确一点, 仅仅只匹配某个元素的孩子节点。
比如, 你想选中是 h1 元素的孩子节点的 strong 元素,而不选中其他后代 strong 元素,可以这样写:
h1 > strong {color: red;}
这里的 >
符号叫做 "child combinator"。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Simple styling of a simple document</title>
<style type="text/css">
html { background-color: white; }
h1 > strong {color: red;}
</style>
</head>
<body>
<h1>This is <strong>very</strong> important.</h1>
<h1>This is <em>really <strong>very</strong></em> important.</h1>
</body>
</html>
4. 选择相邻兄弟元素
要选择紧跟同一父元素的另一个元素的元素,可以使用相邻兄弟组合器(adjacent-sibling combinator),表示为加号 (+)。
比如,
当你要删除紧跟 <h1>
元素的段落的上边距, 可以这样写:
h1 + p {margin-top: 0;}
这里看一个 li + li
的例子:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Simple styling of a simple document</title>
<style type="text/css">
html { background-color: white; }
li + li {font-weight: bold;}
</style>
</head>
<body>
<div>
<ol>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
</ol>
This is some text that is part of the 'div'.
<ul>
<li>A list item</li>
<li>Another list item</li>
<li>Yet another list item</li>
</ul>
</div>
</body>
</html>
5. 选择后续兄弟元素
通用兄弟组合器(general sibling combinator)允许你选择任何位于另一个元素之后的元素,当两个元素共享同一个父元素时,使用波浪号 (~) 组合器表示。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Simple styling of a simple document</title>
<style type="text/css">
html { background-color: white; }
h2 ~ ol {font-style: italic;}
</style>
</head>
<body>
<div>
<h2>Subheadings</h2>
<p>It is the case that not every heading can be a main heading. Some headings must be
subheadings. Examples include:</p>
<ol>
<li>Headings that are less important</li>
<li>Headings that are subsidiary to more important headlines</li>
<li>Headings that like to be dominated</li>
</ol>
<p>Let’s restate that for the record:
<ol>
<li>Headings that are less important</li>
<li>Headings that are subsidiary to more important headlines</li>
<li>Headings that like to be dominated</li>
</ol>
</div>
</body>
</html>
这里的两个 ol 都处于 h2之后,并和 h2 有相同的父元素, 因此该条规则匹配这两个 ol.