01-选择器与优先级
📋 学习目标
掌握所有CSS选择器类型
理解CSS优先级计算规则
学习选择器性能优化
掌握继承和层叠规则
🎯 基本选择器
通用选择器
/* 选择所有元素 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 性能影响:慎用 */
元素选择器
/* 选择所有p元素 */
p {
line-height: 1.6;
color: #333;
}
h1 {
font-size: 2em;
margin-bottom: 0.5em;
}
/* 多个元素 */
h1, h2, h3, h4, h5, h6 {
font-family: 'Arial', sans-serif;
}
类选择器
/* 选择class="button"的元素 */
.button {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
}
/* 多个类 */
.button.primary {
background-color: #ff6b6b;
}
/* 同时有两个类 */
.card.featured {
border: 2px solid gold;
}
ID选择器
/* 选择id="header"的元素 */
#header {
background-color: #fff;
padding: 20px;
}
/* 注意:ID在页面中应该是唯一的 */
/* 避免过度使用ID选择器,优先级过高 */
🔗 组合选择器
后代选择器
/* 选择article内的所有p元素 */
article p {
color: #555;
}
/* 多层嵌套 */
.sidebar .widget ul li {
list-style: none;
}
/* 性能考虑:避免过深嵌套 */
子选择器
/* 只选择直接子元素 */
.menu > li {
display: inline-block;
}
/* 与后代选择器对比 */
.menu li { } /* 所有后代li */
.menu > li { } /* 只有直接子li */
相邻兄弟选择器
/* 选择h1后面紧邻的p元素 */
h1 + p {
font-size: 1.2em;
color: #666;
}
/* 示例 */
/* <h1>标题</h1>
<p>这段会被选中</p>
<p>这段不会被选中</p> */
通用兄弟选择器
/* 选择h1后面所有的p元素 */
h1 ~ p {
margin-top: 1em;
}
/* 示例 */
/* <h1>标题</h1>
<p>会被选中</p>
<div>...</div>
<p>也会被选中</p> */
🎨 属性选择器
基本属性选择器
/* 存在属性 */
[title] {
cursor: help;
}
/* 精确匹配 */
[type="text"] {
border: 1px solid #ddd;
}
input[type="submit"] {
background-color: #007bff;
color: white;
}
/* 多个属性 */
input[type="text"][required] {
border-color: #ff6b6b;
}
模糊匹配
/* 以...开始 */
a[href^="https"] {
color: green;
}
a[href^="http://"] {
color: blue;
}
/* 以...结束 */
a[href$=".pdf"] {
background: url('pdf-icon.png') no-repeat;
padding-left: 20px;
}
img[src$=".jpg"],
img[src$=".png"] {
border: 1px solid #ddd;
}
/* 包含... */
a[href*="example"] {
font-weight: bold;
}
[class*="col-"] {
float: left;
}
其他匹配
/* 以空格分隔的单词中包含 */
[class~="featured"] {
background-color: yellow;
}
/* 以连字符分隔,以...开始 */
[lang|="en"] {
font-family: Arial;
}
/* 匹配 lang="en" 或 lang="en-US" */
🎭 伪类选择器
链接和用户行为
/* 未访问的链接 */
a:link {
color: blue;
}
/* 已访问的链接 */
a:visited {
color: purple;
}
/* 鼠标悬停 */
a:hover {
color: red;
text-decoration: underline;
}
/* 激活状态(点击瞬间) */
a:active {
color: orange;
}
/* 获得焦点 */
input:focus {
outline: 2px solid #007bff;
border-color: #007bff;
}
/* 顺序很重要:LVHA(LoVe HAte) */
结构伪类
/* 第一个子元素 */
li:first-child {
font-weight: bold;
}
/* 最后一个子元素 */
li:last-child {
border-bottom: none;
}
/* 第n个子元素 */
li:nth-child(2) {
background-color: #f0f0f0;
}
/* 奇数行 */
tr:nth-child(odd) {
background-color: #f9f9f9;
}
/* 偶数行 */
tr:nth-child(even) {
background-color: #fff;
}
/* 公式:an + b */
li:nth-child(3n) {
/* 每3个:3, 6, 9, ... */
}
li:nth-child(3n+1) {
/* 3, 6, 9... 的下一个:1, 4, 7, ... */
}
/* 倒数第n个 */
li:nth-last-child(2) {
color: red;
}
/* 唯一子元素 */
p:only-child {
margin: 0;
}
类型伪类
/* 同类型中的第一个 */
p:first-of-type {
font-size: 1.2em;
}
/* 同类型中的最后一个 */
p:last-of-type {
margin-bottom: 0;
}
/* 同类型中的第n个 */
p:nth-of-type(2) {
color: blue;
}
/* 唯一的同类型元素 */
p:only-of-type {
text-align: center;
}
表单伪类
/* 启用状态 */
input:enabled {
background-color: white;
}
/* 禁用状态 */
input:disabled {
background-color: #f0f0f0;
cursor: not-allowed;
}
/* 选中状态(单选框、复选框) */
input:checked + label {
font-weight: bold;
}
/* 必填字段 */
input:required {
border-left: 3px solid #ff6b6b;
}
/* 可选字段 */
input:optional {
border-left: 3px solid #ddd;
}
/* 有效输入 */
input:valid {
border-color: #51cf66;
}
/* 无效输入 */
input:invalid {
border-color: #ff6b6b;
}
/* 范围内 */
input:in-range {
border-color: green;
}
/* 超出范围 */
input:out-of-range {
border-color: red;
}
/* 只读 */
input:read-only {
background-color: #f5f5f5;
}
/* 可读写 */
input:read-write {
background-color: white;
}
其他伪类
/* 空元素 */
p:empty {
display: none;
}
/* 非... */
li:not(.active) {
opacity: 0.5;
}
/* 目标元素(URL锚点) */
:target {
background-color: yellow;
animation: highlight 2s;
}
/* 根元素 */
:root {
--main-color: #007bff;
--spacing: 16px;
}
👻 伪元素选择器
::before和::after
/* 在元素前插入内容 */
.quote::before {
content: '"';
font-size: 2em;
color: #ddd;
}
.quote::after {
content: '"';
font-size: 2em;
color: #ddd;
}
/* 装饰性图标 */
.external-link::after {
content: ' ↗';
font-size: 0.8em;
}
/* 清除浮动 */
.clearfix::after {
content: '';
display: table;
clear: both;
}
/* 创建几何图形 */
.triangle::before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #000;
}
其他伪元素
/* 首字母 */
p::first-letter {
font-size: 2em;
font-weight: bold;
float: left;
line-height: 1;
margin-right: 5px;
}
/* 首行 */
p::first-line {
font-weight: bold;
color: #333;
}
/* 选中文本 */
::selection {
background-color: #ff6b6b;
color: white;
}
/* 占位符文本 */
input::placeholder {
color: #999;
font-style: italic;
}
📊 优先级(特异性)
优先级计算
优先级由四个部分组成:(a, b, c, d)
a: 内联样式(style属性)
b: ID选择器的数量
c: 类、属性、伪类选择器的数量
d: 元素、伪元素选择器的数量
/* 优先级示例 */
* { } /* (0, 0, 0, 0) */
li { } /* (0, 0, 0, 1) */
ul li { } /* (0, 0, 0, 2) */
.list { } /* (0, 0, 1, 0) */
.list li { } /* (0, 0, 1, 1) */
.list .item { } /* (0, 0, 2, 0) */
#header { } /* (0, 1, 0, 0) */
#header .nav { } /* (0, 1, 1, 0) */
#header .nav li { } /* (0, 1, 1, 1) */
style="color: red" /* (1, 0, 0, 0) */
/* !important */
.button {
color: blue !important; /* 最高优先级 */
}
优先级规则
/* 规则1:特异性高的优先 */
p { color: black; } /* (0,0,0,1) */
.text { color: blue; } /* (0,0,1,0) - 优先 */
/* 规则2:特异性相同,后面的优先 */
.button { color: red; }
.button { color: blue; } /* 优先 */
/* 规则3:!important最高 */
.text { color: green !important; }
/* 规则4:内联样式高于外部样式 */
<div class="text" style="color: purple;"> /* 内联优先 */
/* 规则5:继承的优先级最低 */
body { color: gray; }
p { } /* 即使为空,也比继承优先级高 */
最佳实践
/* ❌ 避免过度使用!important */
.button {
color: red !important;
}
/* ✅ 提高选择器特异性 */
.header .button {
color: red;
}
/* ❌ 避免过深嵌套 */
.nav ul li a span { }
/* ✅ 使用类选择器 */
.nav-link-text { }
/* ❌ 避免ID选择器样式 */
#sidebar { }
/* ✅ 使用类选择器 */
.sidebar { }
🔄 继承
可继承属性
/* 文本相关(大部分可继承) */
body {
color: #333; /* 继承 */
font-family: Arial; /* 继承 */
font-size: 16px; /* 继承 */
line-height: 1.6; /* 继承 */
text-align: left; /* 继承 */
}
/* 列表相关 */
ul {
list-style-type: none; /* 继承 */
}
/* 表格相关 */
table {
border-collapse: collapse; /* 继承 */
}
不可继承属性
/* 盒模型 */
div {
width: 100px; /* 不继承 */
height: 100px; /* 不继承 */
margin: 10px; /* 不继承 */
padding: 10px; /* 不继承 */
border: 1px solid; /* 不继承 */
}
/* 定位 */
.element {
position: absolute; /* 不继承 */
top: 0; /* 不继承 */
left: 0; /* 不继承 */
}
/* 背景 */
.box {
background-color: red; /* 不继承 */
}
控制继承
/* inherit:强制继承 */
.child {
border: inherit;
}
/* initial:重置为初始值 */
.element {
color: initial;
}
/* unset:可继承则继承,否则initial */
.element {
color: unset;
}
/* revert:恢复到浏览器默认样式 */
.element {
all: revert;
}
🎯 选择器性能
性能排序(快→慢)
/* 1. ID选择器(最快) */
#header { }
/* 2. 类选择器 */
.button { }
/* 3. 元素选择器 */
div { }
/* 4. 相邻兄弟选择器 */
h1 + p { }
/* 5. 子选择器 */
ul > li { }
/* 6. 后代选择器 */
ul li { }
/* 7. 通配符选择器 */
* { }
/* 8. 属性选择器(最慢) */
[type="text"] { }
优化建议
/* ❌ 避免 */
* { }
div div div div { }
[type="text"] { }
/* ✅ 推荐 */
.specific-class { }
#unique-id { }
/* ❌ 过度限定 */
ul li.item { }
div.container { }
/* ✅ 简洁选择器 */
.item { }
.container { }
/* ❌ 链式选择器过长 */
.header .nav .menu .item .link { }
/* ✅ 使用更具体的类名 */
.nav-link { }
📚 实践练习
练习1:选择器练习
为以下HTML编写CSS:
第一个段落字体加粗
偶数行表格背景色
外部链接添加图标
必填输入框左边框红色
练习2:优先级计算
计算以下选择器的优先级:
#nav .menu li a.container div.boxul > li:first-child[type="text"]:focus
练习3:伪类应用
实现以下效果:
鼠标悬停改变颜色
奇偶行不同背景
选中复选框后标签加粗
表单验证视觉反馈