组合选择器通过选择器之间的关系来选择元素,它们能够让我们更精确地定位目标元素。掌握组合选择器对于编写高效的 CSS 样式至关重要。
后代选择器(也称为包含选择器)选择某个元素的所有后代元素,无论嵌套多深。
祖先元素 后代元素 {
属性: 值;
}
/* 选择所有 div 内的段落元素 */
div p {
margin-bottom: 15px;
line-height: 1.6;
}
/* 选择所有 nav 内的链接元素 */
nav a {
color: white;
text-decoration: none;
}
/* 选择所有 article 内的标题元素 */
article h1, article h2, article h3 {
color: #2c3e50;
margin-bottom: 15px;
}
/* 导航栏样式 */
.main-nav ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-nav ul li {
display: inline-block;
margin-right: 20px;
}
.main-nav ul li a {
color: white;
text-decoration: none;
padding: 10px 15px;
display: block;
}
.main-nav ul li a:hover {
background: rgba(255,255,255,0.1);
}
/* 文章样式 */
.article p {
line-height: 1.8;
margin-bottom: 15px;
color: #555;
}
.article img {
max-width: 100%;
height: auto;
margin: 20px 0;
}
.article blockquote {
border-left: 4px solid #3498db;
padding-left: 20px;
margin: 20px 0;
color: #666;
font-style: italic;
}
后代选择器适用于以下情况:
后代选择器会匹配所有后代元素,可能导致意外的样式应用:
/* 这会影响 div 内的所有段落,无论嵌套多深 */
div p {
color: blue;
}
/* HTML 结构 */
<div>
<p>直接子段落</p>
<div>
<p>嵌套段落</p>
</div>
</div>
/* 两个段落都会被选中 */
子元素选择器只选择某个元素的直接子元素,不包括更深层的后代元素。
父元素 > 子元素 {
属性: 值;
}
/* 只选择 ul 的直接子元素 li */
ul > li {
margin-bottom: 10px;
}
/* 只选择 nav 的直接子元素 a */
nav > a {
font-weight: bold;
text-transform: uppercase;
}
/* 只选择 table 的直接子元素 tbody */
table > tbody {
background: #f5f5f5;
}
/* 导航菜单 */
.nav-menu > li {
display: inline-block;
position: relative;
}
.nav-menu > li > a {
display: block;
padding: 15px 20px;
color: white;
text-decoration: none;
}
.nav-menu > li > a:hover {
background: #555;
}
/* 下拉菜单 */
.dropdown > .dropdown-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
background: white;
min-width: 200px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.dropdown:hover > .dropdown-menu {
display: block;
}
/* 卡片容器 */
.card-group > .card {
display: inline-block;
vertical-align: top;
width: calc(33.333% - 20px);
margin: 10px;
}
子元素选择器适用于以下情况:
/* 后代选择器 - 选中所有后代 */
div p {
color: blue;
}
/* 子元素选择器 - 只选中直接子元素 */
div > p {
color: red;
}
/* HTML 结构 */
<div>
<p>直接子段落(红色)</p>
<div>
<p>嵌套段落(蓝色)</p>
</div>
</div>
相邻兄弟选择器选择紧接在某个元素之后的兄弟元素,两者必须有相同的父元素。
元素1 + 元素2 {
属性: 值;
}
/* 选择紧接在 h1 之后的段落 */
h1 + p {
font-size: 18px;
font-weight: bold;
color: #333;
}
/* 选择紧接在 li 之后的 li */
li + li {
margin-top: 10px;
}
/* 选择紧接在 .title 之后的 .content */
.title + .content {
padding-top: 20px;
border-top: 1px solid #ddd;
}
/* 文章排版 */
.article h2 + p {
margin-top: 0;
font-weight: bold;
}
/* 列表样式 */
.features-list li + li {
margin-top: 15px;
}
.features-list li + li::before {
content: "→ ";
color: #3498db;
}
/* 表单样式 */
.form-group + .form-group {
margin-top: 20px;
}
.form-group label + input {
margin-top: 5px;
}
/* 卡片列表 */
.card + .card {
margin-top: 20px;
}
相邻兄弟选择器适用于以下情况:
相邻兄弟选择器只选择紧接在后面的第一个兄弟元素:
/* 只选择第一个相邻的 li */
li + li {
margin-top: 10px;
}
/* HTML 结构 */
<ul>
<li>项目 1</li>
<li>项目 2 - 有上边距</li>
<li>项目 3 - 有上边距</li>
<li>项目 4 - 有上边距</li>
</ul>
通用兄弟选择器选择某个元素之后的所有兄弟元素。
元素1 ~ 元素2 {
属性: 值;
}
/* 选择 h1 之后的所有段落 */
h1 ~ p {
color: #666;
}
/* 选择 .active 之后的所有列表项 */
.active ~ li {
opacity: 0.7;
}
/* 选择 input 之后的所有 label */
input ~ label {
margin-left: 10px;
}
/* 表单反馈 */
input:focus ~ .hint {
display: block;
color: #666;
font-size: 14px;
}
input:valid ~ .success-icon {
display: inline-block;
color: #28a745;
}
input:invalid ~ .error-icon {
display: inline-block;
color: #dc3545;
}
/* 选项卡 */
.tab:checked ~ .tab-content {
display: block;
}
.tab-content {
display: none;
}
/* 图片画廊 */
img:hover ~ figcaption {
opacity: 1;
}
通用兄弟选择器适用于以下情况:
组合选择器的优先级计算是将所有选择器的优先级相加:
/* 优先级:0,0,2 */
div p {
color: blue;
}
/* 优先级:0,1,1 */
div .text {
color: green;
}
/* 优先级:0,2,0 */
.text1 + .text2 {
color: red;
}
不同的组合选择器对性能的影响不同:
/* 不推荐 - 过度嵌套 */
body div.container div.content div.article div.title h1 {
font-size: 24px;
}
/* 推荐 - 使用类选择器 */
.article-title {
font-size: 24px;
}
/* 不推荐 - 深层后代选择器 */
.main-nav ul li a span {
color: white;
}
/* 推荐 - 使用类选择器 */
.nav-link-text {
color: white;
}
/* 导航容器 */
.main-nav {
background: #2c3e50;
padding: 0 20px;
}
/* 导航列表 */
.main-nav > ul {
list-style: none;
margin: 0;
padding: 0;
}
/* 导航项 */
.main-nav > ul > li {
display: inline-block;
position: relative;
}
/* 导航链接 */
.main-nav > ul > li > a {
display: block;
padding: 15px 20px;
color: white;
text-decoration: none;
}
/* 导航链接悬停 */
.main-nav > ul > li > a:hover {
background: #34495e;
}
/* 下拉菜单 */
.main-nav > ul > li > ul {
display: none;
position: absolute;
top: 100%;
left: 0;
background: #34495e;
min-width: 200px;
}
/* 下拉菜单项 */
.main-nav > ul > li > ul > li {
display: block;
}
/* 下拉菜单链接 */
.main-nav > ul > li > ul > li > a {
padding: 12px 20px;
display: block;
color: white;
text-decoration: none;
}
/* 显示下拉菜单 */
.main-nav > ul > li:hover > ul {
display: block;
}
/* 文章容器 */
.article {
max-width: 800px;
margin: 0 auto;
padding: 40px 20px;
}
/* 文章标题 */
.article h1 {
font-size: 32px;
color: #2c3e50;
margin-bottom: 20px;
}
/* 文章元信息 */
.article h1 + .meta {
color: #666;
font-size: 14px;
margin-bottom: 30px;
}
/* 文章内容 */
.article > p {
line-height: 1.8;
margin-bottom: 20px;
color: #555;
}
/* 文章中的标题 */
.article > h2 {
font-size: 24px;
color: #34495e;
margin-top: 40px;
margin-bottom: 15px;
}
/* 文章中的列表 */
.article > ul {
margin: 20px 0;
padding-left: 30px;
}
/* 文章中的列表项 */
.article > ul > li {
margin-bottom: 10px;
}
/* 文章中的代码块 */
.article > pre {
background: #f5f5f5;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
margin: 20px 0;
}
/* 文章中的图片 */
.article > img {
max-width: 100%;
height: auto;
margin: 30px 0;
}
组合选择器让我们能够更精确地选择元素,是编写高效 CSS 的重要工具:
> 分隔+ 分隔~ 分隔记住以下几点:
在接下来的章节中,我们将学习属性选择器、伪类选择器和伪元素选择器,进一步提高选择 CSS 元素的能力。