CSS选择器
概述
CSS选择器是CSS的核心组成部分,用于定位HTML文档中的元素并应用样式。掌握CSS选择器是前端开发的基础技能。本文将详细介绍各种CSS选择器的用法、特性和最佳实践。
1. 基础选择器
1.1 元素选择器(类型选择器)
/* 选择所有段落元素 */
p {
color: #333;
font-size: 16px;
}
/* 选择所有标题元素 */
h1, h2, h3 {
font-weight: bold;
margin-top: 1em;
}
/* 选择所有链接 */
a {
text-decoration: none;
color: #007bff;
}
1.2 类选择器
/* 选择具有特定类的元素 */
.highlight {
background-color: yellow;
font-weight: bold;
}
/* 选择具有多个类的元素 */
.card.primary {
border: 2px solid #007bff;
}
/* 多个类选择器组合 */
.btn.btn-large {
padding: 12px 24px;
font-size: 18px;
}
/* 类选择器与元素选择器结合 */
div.container {
max-width: 1200px;
margin: 0 auto;
}
1.3 ID选择器
/* 选择具有特定ID的元素 */
#header {
background-color: #f8f9fa;
padding: 20px;
}
/* ID选择器与元素选择器结合 */
nav#main-navigation {
background-color: #343a40;
}
/* 注意:ID选择器具有最高特异性,应谨慎使用 */
1.4 通用选择器
/* 选择所有元素 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* 选择特定元素内的所有子元素 */
.container * {
border: 1px solid #ddd;
}
/* 与其他选择器结合 */
.article * {
line-height: 1.6;
}
2. 组合选择器
2.1 后代选择器(空格)
/* 选择div元素内的所有p元素 */
div p {
margin-bottom: 1em;
}
/* 选择导航栏内的所有链接 */
nav ul li a {
color: #333;
text-decoration: none;
}
/* 多层嵌套的后代选择器 */
.container .content .article .paragraph {
font-size: 16px;
line-height: 1.6;
}
/* 实际应用:侧边栏导航样式 */
.sidebar .nav .nav-item .nav-link {
display: block;
padding: 8px 16px;
color: #666;
}
2.2 子元素选择器(>)
/* 只选择直接子元素 */
ul > li {
list-style-type: disc;
}
/* 与后代选择器的区别 */
/* 后代选择器:选择所有后代 */
div p {
color: blue;
}
/* 子选择器:只选择直接子元素 */
div > p {
color: red;
}
/* 多级子选择器 */
nav > ul > li > a {
font-weight: bold;
}
/* 实际应用:表格样式 */
table > thead > tr > th {
background-color: #f8f9fa;
font-weight: bold;
text-align: left;
}
table > tbody > tr > td {
padding: 12px;
border-bottom: 1px solid #dee2e6;
}
2.3 相邻兄弟选择器(+)
/* 选择紧跟在h1后面的p元素 */
h1 + p {
font-size: 1.2em;
color: #666;
margin-top: 0;
}
/* 选择紧跟在input后面的label */
input + label {
margin-left: 8px;
}
/* 实际应用:表单布局 */
.form-group > label + input {
margin-top: 4px;
}
/* 标题与内容的间距 */
h2 + p {
margin-top: 0.5em;
}
/* 错误消息样式 */
input.error + .error-message {
color: #dc3545;
font-size: 0.875em;
margin-top: 4px;
}
2.4 通用兄弟选择器(~)
/* 选择h2后面所有的p兄弟元素 */
h2 ~ p {
margin-left: 20px;
}
/* 选择checkbox后面所有的label */
input[type="checkbox"] ~ label {
cursor: pointer;
}
/* 实际应用:选项卡内容 */
.tab:checked ~ .tab-content {
display: block;
}
.tab ~ .tab-content {
display: none;
}
/* 导航菜单激活状态 */
.nav-item.active ~ .nav-item {
opacity: 0.7;
}
3. 属性选择器
3.1 基本属性选择器
/* 选择具有特定属性的元素 */
[title] {
cursor: help;
border-bottom: 1px dotted #666;
}
/* 选择具有特定属性值的元素 */
[type="text"] {
border: 1px solid #ced4da;
padding: 8px 12px;
}
/* 选择具有特定类名的元素 */
[class="highlight"] {
background-color: yellow;
}
/* 多个属性选择器组合 */
input[type="email"][required] {
border-color: #28a745;
}
3.2 属性值匹配选择器
/* 属性值以特定字符串开头 */
[href^="https"] {
color: #28a745;
}
[href^="http"]::after {
content: " ↗";
font-size: 0.8em;
}
/* 属性值以特定字符串结尾 */
[href$=".pdf"] {
color: #dc3545;
}
[href$=".pdf"]::before {
content: "📄 ";
}
/* 属性值包含特定字符串 */
[class*="btn"] {
display: inline-block;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}
/* 属性值包含独立单词 */
[class~="active"] {
background-color: #007bff;
color: white;
}
/* 属性值等于或以特定字符串开头(用于语言选择) */
[lang|="en"] {
font-family: 'Arial', sans-serif;
}
3.3 实际应用示例
/* 外部链接样式 */
a[href^="http"]:not([href*="example.com"]) {
color: #dc3545;
}
a[href^="http"]:not([href*="example.com"])::after {
content: " ↗";
color: #6c757d;
}
/* 文件类型图标 */
a[href$=".pdf"]::before { content: "📄 "; }
a[href$=".doc"]::before { content: "📝 "; }
a[href$=".xls"]::before { content: "📊 "; }
a[href$=".zip"]::before { content: "📦 "; }
/* 表单验证样式 */
input[required] {
border-left: 3px solid #ffc107;
}
input[required]:valid {
border-left-color: #28a745;
}
input[required]:invalid {
border-left-color: #dc3545;
}
/* 图片响应式 */
img[alt][src] {
max-width: 100%;
height: auto;
}
4. 伪类选择器
4.1 动态伪类
/* :link - 未访问的链接 */
a:link {
color: #007bff;
}
/* :visited - 已访问的链接 */
a:visited {
color: #6c757d;
}
/* :hover - 鼠标悬停 */
button:hover {
background-color: #0056b3;
transform: translateY(-1px);
}
/* :active - 激活状态 */
button:active {
transform: translateY(0);
}
/* :focus - 获得焦点 */
input:focus {
outline: none;
border-color: #80bdff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
4.2 结构性伪类
/* :first-child - 第一个子元素 */
li:first-child {
border-top: none;
}
/* :last-child - 最后一个子元素 */
li:last-child {
border-bottom: none;
}
/* :nth-child(n) - 第n个子元素 */
li:nth-child(odd) {
background-color: #f8f9fa;
}
li:nth-child(even) {
background-color: #ffffff;
}
/* :nth-child(an+b) - 公式选择 */
li:nth-child(3n+1) {
font-weight: bold;
}
/* :nth-last-child(n) - 倒数第n个子元素 */
li:nth-last-child(2) {
border-bottom: 2px solid #007bff;
}
/* :only-child - 唯一子元素 */
p:only-child {
font-style: italic;
}
/* :first-of-type - 同类型第一个元素 */
p:first-of-type {
margin-top: 0;
}
/* :last-of-type - 同类型最后一个元素 */
p:last-of-type {
margin-bottom: 0;
}
/* :nth-of-type(n) - 同类型第n个元素 */
h2:nth-of-type(2) {
color: #007bff;
}
/* :only-of-type - 唯一同类型元素 */
img:only-of-type {
display: block;
margin: 0 auto;
}
4.3 UI状态伪类
/* :checked - 被选中的复选框或单选框 */
input[type="checkbox"]:checked + label {
color: #28a745;
font-weight: bold;
}
/* :disabled - 禁用的表单元素 */
input:disabled {
background-color: #e9ecef;
cursor: not-allowed;
opacity: 0.6;
}
/* :enabled - 启用的表单元素 */
input:enabled {
background-color: white;
}
/* :required - 必填字段 */
input:required {
border-left: 3px solid #dc3545;
}
/* :optional - 可选字段 */
input:optional {
border-left: 3px solid #6c757d;
}
/* :valid - 验证通过 */
input:valid {
border-color: #28a745;
}
/* :invalid - 验证失败 */
input:invalid {
border-color: #dc3545;
}
/* :read-only - 只读字段 */
input:read-only {
background-color: #f8f9fa;
cursor: not-allowed;
}
/* :read-write - 可读写字段 */
input:read-write {
background-color: white;
}
4.4 逻辑性伪类
/* :not() - 否定伪类 */
button:not([disabled]) {
cursor: pointer;
}
a:not([href^="http"]) {
color: #6c757d;
}
/* :is() - 匹配任意选择器 */
:is(h1, h2, h3) {
font-family: 'Arial', sans-serif;
color: #333;
}
/* :where() - 低优先级选择器 */
:where(.btn, .button) {
padding: 8px 16px;
border: none;
border-radius: 4px;
}
/* :has() - 父元素选择器 */
article:has(h2) {
border-top: 2px solid #007bff;
}
div:has(> .highlight) {
background-color: #f8f9fa;
}
/* :lang() - 语言选择器 */
p:lang(en) {
quotes: '"' '"' "'" "'";
}
p:lang(zh) {
quotes: """ """ "'" "'";
}
5. 伪元素选择器
5.1 基础伪元素
/* ::before - 元素前插入内容 */
.quote::before {
content: """;
font-size: 2em;
color: #6c757d;
margin-right: 8px;
}
/* ::after - 元素后插入内容 */
.quote::after {
content: """;
font-size: 2em;
color: #6c757d;
margin-left: 8px;
}
/* ::first-letter - 首字母 */
p::first-letter {
font-size: 3em;
font-weight: bold;
float: left;
line-height: 1;
margin-right: 8px;
}
/* ::first-line - 首行 */
p::first-line {
font-weight: bold;
color: #333;
}
/* ::selection - 选中文本 */
::selection {
background-color: #007bff;
color: white;
}
/* ::placeholder - 占位符文本 */
input::placeholder {
color: #6c757d;
font-style: italic;
}
/* ::marker - 列表标记 */
li::marker {
color: #007bff;
font-weight: bold;
}
5.2 高级伪元素应用
/* 清除浮动 */
.clearfix::after {
content: "";
display: table;
clear: both;
}
/* 装饰性元素 */
.card::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, #007bff, #28a745);
}
/* 工具提示 */
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover::after {
opacity: 1;
}
/* 加载动画 */
.loading::before {
content: "";
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid #f3f3f3;
border-top: 2px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 响应式图片容器 */
.image-container::before {
content: "";
display: block;
padding-top: 56.25%; /* 16:9 宽高比 */
}
.image-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
6. 选择器优先级
6.1 优先级计算
/* 优先级从高到低:
1. !important
2. 内联样式 (1000)
3. ID选择器 (100)
4. 类选择器、属性选择器、伪类 (10)
5. 元素选择器、伪元素 (1)
6. 通用选择器 (0)
*/
/* 示例优先级计算 */
/* 优先级:1 (元素选择器) */
p { color: black; }
/* 优先级:10 (类选择器) */
.highlight { color: yellow; }
/* 优先级:11 (元素 + 类) */
p.highlight { color: orange; }
/* 优先级:100 (ID选择器) */
#special { color: red; }
/* 优先级:111 (ID + 元素 + 类) */
#special p.highlight { color: green; }
/* !important - 最高优先级(谨慎使用) */
p { color: blue !important; }
6.2 优先级最佳实践
/* 避免!important,使用更具体的选择器 */
/* 不推荐 */
.text { color: red !important; }
/* 推荐 */
.card .title .text { color: red; }
/* 使用CSS变量避免!important */
:root {
--primary-color: #007bff;
--text-color: #333;
}
.button {
color: var(--primary-color);
}
.button.disabled {
color: var(--text-color);
}
/* 使用BEM命名规范提高可维护性 */
.card { /* 块 */ }
.card__title { /* 元素 */ }
.card--highlighted { /* 修饰符 */ }
7. 实际应用示例
7.1 导航菜单样式
/* 主导航 */
.nav {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.nav-item {
position: relative;
}
.nav-link {
display: block;
padding: 12px 16px;
text-decoration: none;
color: #333;
transition: all 0.3s ease;
}
.nav-link:hover {
background-color: #f8f9fa;
color: #007bff;
}
.nav-item.active > .nav-link {
color: #007bff;
font-weight: bold;
}
/* 下拉菜单 */
.nav-item:hover > .dropdown {
display: block;
}
.dropdown {
display: none;
position: absolute;
top: 100%;
left: 0;
background-color: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
min-width: 200px;
}
.dropdown-item {
display: block;
padding: 8px 16px;
color: #333;
text-decoration: none;
}
.dropdown-item:hover {
background-color: #f8f9fa;
}
7.2 表单样式
/* 表单容器 */
.form-group {
margin-bottom: 1rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: #333;
}
.form-control {
display: block;
width: 100%;
padding: 0.75rem 1rem;
font-size: 1rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 0.375rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.form-control:focus {
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
/* 表单验证状态 */
.form-control.is-valid {
border-color: #28a745;
}
.form-control.is-invalid {
border-color: #dc3545;
}
/* 错误消息 */
.invalid-feedback {
display: none;
width: 100%;
margin-top: 0.25rem;
font-size: 0.875em;
color: #dc3545;
}
.form-control.is-invalid ~ .invalid-feedback {
display: block;
}
/* 必填字段标识 */
.required::after {
content: " *";
color: #dc3545;
}
7.3 卡片组件
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 0.375rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.card-header {
padding: 1rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
border-top-left-radius: calc(0.375rem - 1px);
border-top-right-radius: calc(0.375rem - 1px);
}
.card-body {
flex: 1 1 auto;
padding: 1.25rem;
}
.card-title {
margin-bottom: 0.75rem;
font-size: 1.25rem;
font-weight: 500;
color: #333;
}
.card-text {
margin-bottom: 1rem;
color: #666;
line-height: 1.6;
}
.card-footer {
padding: 0.75rem 1.25rem;
background-color: rgba(0, 0, 0, 0.03);
border-top: 1px solid rgba(0, 0, 0, 0.125);
border-bottom-right-radius: calc(0.375rem - 1px);
border-bottom-left-radius: calc(0.375rem - 1px);
}
/* 卡片变体 */
.card-primary {
border-color: #007bff;
}
.card-primary .card-header {
background-color: #007bff;
color: white;
border-bottom-color: #007bff;
}
.card-highlight {
border-left: 4px solid #007bff;
}
7.4 表格样式
.table {
width: 100%;
margin-bottom: 1rem;
color: #212529;
border-collapse: collapse;
}
.table th,
.table td {
padding: 0.75rem;
vertical-align: top;
border-top: 1px solid #dee2e6;
text-align: left;
}
.table thead th {
vertical-align: bottom;
border-bottom: 2px solid #dee2e6;
border-top: none;
background-color: #f8f9fa;
font-weight: 600;
}
.table tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.02);
}
.table tbody tr:hover {
background-color: #f8f9fa;
}
.table-striped tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.05);
}
.table-bordered {
border: 1px solid #dee2e6;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #dee2e6;
}
/* 表格状态 */
.table-success,
.table-success > th,
.table-success > td {
background-color: #d4edda;
}
.table-warning,
.table-warning > th,
.table-warning > td {
background-color: #fff3cd;
}
.table-danger,
.table-danger > th,
.table-danger > td {
background-color: #f8d7da;
}
8. 性能优化
8.1 选择器性能
/* 高性能选择器(从右到左解析) */
/* 推荐:简单的类选择器 */
.button { /* 快速 */ }
/* 推荐:直接的子选择器 */
.nav > .nav-item { /* 较快 */ }
/* 避免:复杂的后代选择器 */
.container .content .article .paragraph .text { /* 慢 */ }
/* 避免:通用选择器 */
.container * { /* 非常慢 */ }
/* 避免:属性选择器(除非必要) */
[type="text"] { /* 较慢 */ }
/* 推荐使用类选择器替代属性选择器 */
.text-input { /* 快速 */ }
8.2 优化建议
/* 1. 使用类选择器为主 */
/* 不推荐 */
div[class="button"] { }
/* 推荐 */
.button { }
/* 2. 避免过度嵌套 */
/* 不推荐 */
.header .nav .nav-item .nav-link .text { }
/* 推荐 */
.nav-link-text { }
/* 3. 使用语义化的类名 */
/* 不推荐 */
.red-bold-large { }
/* 推荐 */
.error-message { }
/* 4. 减少选择器复杂度 */
/* 不推荐 */
body > div.container > main > article > section > p { }
/* 推荐 */
.article-text { }
/* 5. 合理使用伪类 */
/* 推荐 */
li:first-child { }
/* 避免 */
li:nth-child(1n+0) { }
9. 现代CSS选择器
9.1 CSS逻辑属性
/* 逻辑属性选择器 */
/* :dir() - 方向选择器 */
p:dir(ltr) {
text-align: left;
}
p:dir(rtl) {
text-align: right;
}
/* :scope - 作用域选择器 */
.scope-container :scope > p {
color: blue;
}
/* :target - 目标选择器 */
.section:target {
background-color: #f8f9fa;
border-left: 4px solid #007bff;
}
9.2 CSS容器查询
/* 容器查询选择器 */
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
/* 容器查询伪类 */
@container card (min-width: 300px) {
.card-title {
font-size: 1.5rem;
}
}
10. 浏览器兼容性
10.1 兼容性注意事项
/* 伪元素语法 */
/* 旧语法(CSS2) */
:pseudo-element { }
/* 新语法(CSS3) */
::pseudo-element { }
/* 伪类支持 */
:is() /* Chrome 88+, Firefox 78+, Safari 14+ */
:where() /* Chrome 88+, Firefox 78+, Safari 14+ */
:has() /* Chrome 105+, Firefox 103+, Safari 15.4+ */
/* 降级方案 */
/* 现代浏览器 */
.card:has(.highlight) {
border-color: #007bff;
}
/* 旧版浏览器 */
.card.highlight {
border-color: #007bff;
}
10.2 前缀处理
/* 浏览器前缀(现在大部分不需要) */
/* 旧版浏览器需要 */
input::-webkit-input-placeholder { /* Chrome, Safari, Opera */ }
input::-moz-placeholder { /* Firefox 19+ */ }
input:-ms-input-placeholder { /* IE 10+ */ }
/* 现代浏览器统一使用 */
input::placeholder { }
11. 最佳实践总结
11.1 命名规范
/* BEM命名法 */
.block { }
.block__element { }
.block--modifier { }
/* 示例 */
.card { }
.card__title { }
.card__content { }
.card--featured { }
.card__title--large { }
/* 语义化命名 */
.header { } /* 而不是 .top-bar */
.navigation { } /* 而不是 .nav-menu */
.content { } /* 而不是 .main-area */
.sidebar { } /* 而不是 .right-column */
.footer { } /* 而不是 .bottom-part */
11.2 组织结构
/* 1. 重置样式 */
* { margin: 0; padding: 0; box-sizing: border-box; }
/* 2. 基础样式 */
html { font-size: 16px; }
body { font-family: Arial, sans-serif; line-height: 1.6; }
/* 3. 布局组件 */
.container { max-width: 1200px; margin: 0 auto; }
.grid { display: grid; }
.flex { display: flex; }
/* 4. 模块组件 */
.button { }
.card { }
.form { }
.table { }
/* 5. 工具类 */
.text-center { text-align: center; }
.hidden { display: none; }
.mt-1 { margin-top: 0.25rem; }
/* 6. 状态类 */
.is-active { }
.is-disabled { }
.is-loading { }
11.3 维护性建议
/* 1. 使用CSS变量 */
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--success-color: #28a745;
--danger-color: #dc3545;
--font-family: Arial, sans-serif;
--border-radius: 0.375rem;
--transition: all 0.3s ease;
}
/* 2. 保持选择器简单 */
/* 不推荐 */
.header nav ul li a span { }
/* 推荐 */
.nav-link-text { }
/* 3. 避免过度具体化 */
/* 不推荐 */
body #main .container .content .article .title { }
/* 推荐 */
.article-title { }
/* 4. 使用注释 */
/* ===================================
按钮组件
=================================== */
.button { }
.button--primary { }
.button--large { }
12 0
评论 (0)
请先登录后再评论
暂无评论