其他选择器
概述
除了常用的选择器外,CSS 还有一些其他有用的选择器,包括目标伪类、语言伪类、空伪类、根选择器等。
其他选择器详解
1. :root - 根元素选择器
选择文档的根元素(HTML 文档中就是 <html> 元素)。常用于定义 CSS 变量。
/* 定义 CSS 变量 */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--bg-color: #fff;
--font-size: 16px;
}
/* 使用变量 */
body {
color: var(--text-color);
background-color: var(--bg-color);
font-size: var(--font-size);
}
.button {
background-color: var(--primary-color);
color: white;
}2. :empty - 空元素选择器
选择没有任何子元素(包括文本节点)的元素。
/* 空盒子隐藏 */
.box:empty {
display: none;
}
/* 空元素显示提示信息 */
.empty-item:empty::after {
content: "暂无内容";
color: #999;
font-style: italic;
}
/* 表格空单元格 */
td:empty {
background-color: #f5f5f5;
}<div class="box"></div>
<!-- 这个 div 是空的,会被隐藏 -->
<div class="box">有内容</div>
<!-- 这个 div 有内容,不会被隐藏 -->
<table>
<tr>
<td>数据1</td>
<td></td> <!-- 空单元格,会应用样式 -->
</tr>
</table>3. :target - 目标伪类选择器
选择当前活动的锚点目标元素(URL 中 # 后面的 ID)。
/* 目标元素高亮 */
.section:target {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
padding: 20px;
animation: highlight 0.5s ease;
}
@keyframes highlight {
0% {
transform: translateX(-10px);
}
50% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}<nav>
<a href="#section1">跳转到第一节</a>
<a href="#section2">跳转到第二节</a>
<a href="#section3">跳转到第三节</a>
</nav>
<div id="section1" class="section">
<h2>第一节</h2>
<p>第一节内容...</p>
</div>
<div id="section2" class="section">
<h2>第二节</h2>
<p>第二节内容...</p>
</div>4. :lang(language) - 语言伪类选择器
选择指定语言的元素。
/* 中文内容 */
p:lang(zh) {
font-family: "Microsoft YaHei", "SimHei", sans-serif;
line-height: 1.8;
}
/* 英文内容 */
p:lang(en) {
font-family: Arial, "Helvetica Neue", sans-serif;
line-height: 1.5;
}
/* 日文内容 */
p:lang(ja) {
font-family: "Hiragino Kaku Gothic Pro", sans-serif;
}<p lang="zh">这是一段中文内容。</p>
<p lang="en">This is English content.</p>
<p lang="ja">これは日本語の内容です。</p>5. :not(selector) - 否定伪类选择器
选择不匹配指定选择器的元素。
/* 不是禁用的输入框 */
input:not(:disabled) {
background-color: #fff;
cursor: pointer;
}
/* 不是第一个的列表项 */
li:not(:first-child) {
border-top: 1px solid #eee;
}
/* 不是最后且不是第一个的元素 */
li:not(:first-child):not(:last-child) {
padding: 0 20px;
}
/* 不是特定类的按钮 */
button:not(.primary):not(.danger) {
background-color: #95a5a6;
}
/* 不包含 data 属性的元素 */
div:not([data-attribute]) {
opacity: 0.7;
}6. :fullscreen - 全屏伪类选择器
选择当前处于全屏模式的元素。
/* 全屏元素 */
:fullscreen {
background-color: black;
width: 100vw;
height: 100vh;
}
/* 全屏时的特定样式 */
.video-container:fullscreen {
display: flex;
align-items: center;
justify-content: center;
}7. ::placeholder - 占位符伪元素选择器
选择输入框的占位符文本。
/* 文本输入框占位符 */
input::placeholder {
color: #999;
font-style: italic;
}
/* 文本域占位符 */
textarea::placeholder {
color: #ccc;
font-size: 14px;
}
/* 聚焦时的占位符 */
input:focus::placeholder {
opacity: 0.5;
}<input type="text" placeholder="请输入用户名">
<textarea placeholder="请输入留言"></textarea>8. ::selection - 选中文本伪元素选择器
选择用户选中的文本。
/* 默认选中文本样式 */
::selection {
background-color: #3498db;
color: white;
}
/* Firefox 需要单独写 */
::-moz-selection {
background-color: #3498db;
color: white;
}
/* 特定元素的选中样式 */
.highlight-text ::selection {
background-color: #e74c3c;
color: white;
}注意: ::selection 只能设置以下属性:
- color
- background-color
- cursor
- outline
- text-decoration
- text-shadow
9. ::backdrop - 背景遮罩伪元素选择器
选择全屏元素(如 dialog)背后的背景遮罩。
/* 模态框背景 */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
}
/* 全屏视频背景 */
video:fullscreen::backdrop {
background-color: black;
}<dialog open>
<h2>模态框标题</h2>
<p>模态框内容</p>
<button onclick="this.parentElement.close()">关闭</button>
</dialog>10. ::marker - 列表标记伪元素选择器
选择列表项的标记(如圆点、数字等)。
/* 自定义无序列表标记 */
ul ::marker {
content: "• ";
color: #3498db;
font-size: 1.5em;
}
/* 自定义有序列表标记 */
ol ::marker {
font-weight: bold;
color: #e74c3c;
}
/* 特定列表的标记 */
.special-list ::marker {
content: "★ ";
color: #f39c12;
}<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
<ol>
<li>有序列表1</li>
<li>有序列表2</li>
</ol>
<ul class="special-list">
<li>特殊列表</li>
</ul>权重计算
| 选择器 | 权重 |
|---|---|
| :root | 0 (根元素) |
| :empty | 10 |
| :target | 10 |
| :lang() | 10 |
| :not() | 0 (权重由内部选择器决定) |
| :fullscreen | 10 |
| ::placeholder | 1 (伪元素) |
| ::selection | 1 (伪元素) |
| ::backdrop | 1 (伪元素) |
| ::marker | 1 (伪元素) |
:root {
/* 权重 = 0 */
}
.box:empty {
/* 权重 = 10 + 10 = 20 */
}
.section:target {
/* 权重 = 10 + 10 = 20 */
}
p:lang(zh) {
/* 权重 = 1 + 10 = 11 */
}
li:not(:first-child) {
/* 权重 = 1 + 10 = 11 (不包含 :first-child 的权重) */
}常见应用场景
1. CSS 变量系统
:root {
/* 颜色变量 */
--primary-color: #3498db;
--secondary-color: #2ecc71;
--accent-color: #e74c3c;
--success-color: #27ae60;
--warning-color: #f39c12;
--danger-color: #c0392b;
/* 间距变量 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* 字体变量 */
--font-size-base: 16px;
--font-size-sm: 14px;
--font-size-lg: 18px;
--font-size-xl: 20px;
/* 圆角变量 */
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 16px;
/* 阴影变量 */
--shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
--shadow-md: 0 2px 8px rgba(0,0,0,0.15);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.2);
}2. 主题切换
:root {
--bg-color: #ffffff;
--text-color: #333333;
--card-bg: #ffffff;
--border-color: #e0e0e0;
}
/* 暗色主题 */
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #ffffff;
--card-bg: #2a2a2a;
--border-color: #404040;
}
/* 应用主题变量 */
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
.card {
background-color: var(--card-bg);
border: 1px solid var(--border-color);
transition: background-color 0.3s ease, border-color 0.3s ease;
}3. 锚点导航
/* 章节样式 */
.section {
padding: 20px;
transition: all 0.3s ease;
}
/* 目标章节高亮 */
.section:target {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
animation: slideIn 0.5s ease;
}
@keyframes slideIn {
from {
transform: translateX(-20px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* 滚动到目标 */
html {
scroll-behavior: smooth;
}4. 空状态处理
/* 空内容提示 */
.empty-content:empty::before {
content: "📭";
display: block;
text-align: center;
font-size: 48px;
margin-bottom: 20px;
}
.empty-content:empty::after {
content: "暂无内容";
display: block;
text-align: center;
color: #999;
font-size: 16px;
}
/* 表格空单元格 */
table td:empty::before {
content: "-";
color: #ccc;
display: block;
text-align: center;
}5. 表单占位符
/* 占位符样式 */
input::placeholder,
textarea::placeholder {
color: #999;
font-style: italic;
transition: color 0.3s ease;
}
/* 聚焦时占位符 */
input:focus::placeholder,
textarea:focus::placeholder {
color: transparent;
}
/* 错误状态占位符 */
input:invalid:not(:placeholder-shown)::placeholder {
color: #e74c3c;
}6. 选中文本样式
/* 全局选中文本 */
::selection {
background-color: #3498db;
color: white;
}
/* 代码块选中文本 */
code::selection {
background-color: #2c3e50;
color: #ecf0f1;
}
/* 引用块选中文本 */
blockquote::selection {
background-color: #e74c3c;
color: white;
}
/* Firefox */
::-moz-selection {
background-color: #3498db;
color: white;
}7. 多语言支持
/* 中文 */
body:lang(zh) {
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
line-height: 1.8;
}
/* 英文 */
body:lang(en) {
font-family: "Helvetica Neue", Arial, sans-serif;
line-height: 1.5;
}
/* 日文 */
body:lang(ja) {
font-family: "Hiragino Kaku Gothic Pro", sans-serif;
line-height: 1.7;
}
/* 韩文 */
body:lang(ko) {
font-family: "Malgun Gothic", sans-serif;
line-height: 1.6;
}8. 否定选择器应用
/* 不是第一个且不是最后一个的元素 */
li:not(:first-child):not(:last-child) {
border-left: 1px solid #eee;
border-right: 1px solid #eee;
padding: 0 20px;
}
/* 不是禁用的按钮 */
button:not(:disabled) {
cursor: pointer;
opacity: 1;
}
/* 不是主按钮且不是危险按钮 */
button:not(.primary):not(.danger) {
background-color: #95a5a6;
color: white;
}
/* 不包含特定类的元素 */
.box:not(.active) {
opacity: 0.7;
}
/* 不是链接的可点击元素 */
[onclick]:not(a) {
cursor: pointer;
}实战案例
案例1: 响应式设计系统
:root {
/* 断点变量 */
--breakpoint-sm: 576px;
--breakpoint-md: 768px;
--breakpoint-lg: 992px;
--breakpoint-xl: 1200px;
/* 容器宽度 */
--container-sm: 540px;
--container-md: 720px;
--container-lg: 960px;
--container-xl: 1140px;
/* 网格列数 */
--grid-columns: 12;
--grid-gutter: 24px;
}
/* 响应式容器 */
.container {
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
@media (min-width: 576px) {
.container {
max-width: var(--container-sm);
}
}
@media (min-width: 768px) {
.container {
max-width: var(--container-md);
}
}
@media (min-width: 992px) {
.container {
max-width: var(--container-lg);
}
}案例2: 文档目录导航
/* 章节样式 */
.section {
padding: 40px 20px;
border-bottom: 1px solid #eee;
}
/* 目标章节 */
.section:target {
background-color: #f0f8ff;
border-left: 5px solid #3498db;
animation: highlight 0.5s ease;
}
@keyframes highlight {
0% {
background-color: #e8f4fd;
}
100% {
background-color: #f0f8ff;
}
}
/* 目录导航 */
.toc {
position: sticky;
top: 20px;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.toc a {
display: block;
padding: 8px 0;
color: #333;
text-decoration: none;
}
.toc a:hover {
color: #3498db;
}
.toc a:target {
color: #3498db;
font-weight: bold;
}案例3: 表单验证系统
:root {
--valid-color: #27ae60;
--invalid-color: #e74c3c;
--warning-color: #f39c12;
}
/* 表单组 */
.form-group {
margin-bottom: 20px;
}
/* 必填字段 */
input:required + label::after {
content: " *";
color: var(--invalid-color);
}
/* 验证通过 */
input:valid:not(:placeholder-shown) {
border-color: var(--valid-color);
}
/* 验证失败 */
input:invalid:not(:placeholder-shown) {
border-color: var(--invalid-color);
}
/* 禁用字段 */
input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
opacity: 0.7;
}
/* 只读字段 */
input:read-only {
background-color: #f9f9f9;
border-color: #ddd;
}案例4: 空状态展示
/* 卡片容器 */
.card-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
/* 空容器提示 */
.card-container:empty::before {
content: "";
display: block;
grid-column: 1 / -1;
padding: 60px 20px;
text-align: center;
background: #f9f9f9;
border-radius: 8px;
border: 2px dashed #ddd;
}
.card-container:empty::after {
content: "暂无卡片数据";
color: #999;
font-size: 18px;
display: block;
margin-top: 20px;
}
/* 列表空状态 */
.list-container:empty {
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #f9f9f9;
border-radius: 8px;
}
.list-container:empty::before {
content: "📭";
font-size: 48px;
margin-right: 10px;
}
.list-container:empty::after {
content: "列表为空";
color: #999;
}案例5: 全屏媒体播放器
/* 视频容器 */
.video-container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 比例 */
background: #000;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* 全屏模式 */
.video-container:fullscreen {
width: 100vw;
height: 100vh;
padding-bottom: 0;
}
.video-container:fullscreen video {
width: 100%;
height: 100%;
object-fit: contain;
}
/* 全屏背景 */
:fullscreen::backdrop {
background-color: black;
}
/* 控制按钮 */
.controls button {
padding: 10px 20px;
background: rgba(255,255,255,0.2);
color: white;
border: none;
cursor: pointer;
border-radius: 4px;
}
.controls button:not(:disabled) {
background: rgba(255,255,255,0.4);
}
.controls button:hover:not(:disabled) {
background: rgba(255,255,255,0.6);
}注意事项
- :root 兼容性: IE8 及以下不支持
- :empty 严格: 元素必须完全空(包括空格)
- :target 行为: 元素必须在 URL 中指定
- :lang 优先级: 低于元素的 lang 属性
- :not() 限制: 不能嵌套,不能使用伪元素
- 伪元素限制: 某些伪元素(如 ::selection)支持的属性有限
- 浏览器差异: 某些选择器在不同浏览器中表现可能不同
最佳实践
- 变量管理: 使用 :root 集中管理 CSS 变量
- 主题系统: 利用 CSS 变量实现主题切换
- 空状态: 合理使用 :empty 处理空状态
- 锚点导航: 使用 :target 实现页面内导航
- 语言适配: 为不同语言设置合适的字体和样式
- 渐进增强: 为不支持的浏览器提供回退方案
- 性能考虑: 避免过度使用复杂选择器
- 代码注释: 复杂选择器添加注释说明
总结
其他选择器虽然使用频率不如基本选择器,但在特定场景下非常有用。掌握这些选择器可以帮助我们:
- 更好地组织和管理 CSS 变量
- 处理各种边界情况(空状态、锚点导航等)
- 实现多语言支持
- 提升用户体验
在实际开发中,要合理使用这些选择器,确保代码的可维护性和性能。