前言
前端开发中,任何样式的实现都始于元素定位 ------ CSS 选择器正是为此而生的核心工具,它让开发者能精准锁定 HTML 元素并施加样式。本文将系统梳理其类型、用法及高级技巧,助你全面掌握这一基础技能。
一、基础选择器
通用选择器 (*)
通用选择器匹配页面上的所有元素。
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
这个选择器通常用于重置浏览器默认样式,但应谨慎使用,因为它会影响文档中的每个元素,可能导致性能问题。
元素选择器
元素选择器根据HTML标签名称选择元素。
css
p {
line-height: 1.6;
}
h1 {
font-size: 2em;
}
类选择器 (.)
类选择器选择具有特定class属性的元素。
css
.container {
width: 80%;
margin: 0 auto;
}
.btn-primary {
background-color: #007bff;
}
ID选择器 (#)
ID选择器选择具有特定id属性的元素。每个ID在页面中应该是唯一的。
css
#header {
position: sticky;
top: 0;
}
#main-content {
padding: 20px;
}
属性选择器
属性选择器根据元素的属性及其值来选择元素。
css
/* 选择所有具有title属性的元素 */
[title] {
cursor: help;
}
/* 选择所有href属性值为"https://example.com"的元素 */
[href="https://example.com"] {
color: purple;
}
/* 选择所有class属性包含"btn"的元素 */
[class*="btn"] {
border-radius: 4px;
}
/* 选择所有以"https"开头的href属性的元素 */
[href^="https"] {
color: green;
}
/* 选择所有以".pdf"结尾的href属性的元素 */
[href$=".pdf"] {
background-image: url('pdf-icon.png');
}
二、组合选择器
后代选择器(空格)
选择某个元素的所有后代元素,不论层级深度。
css
article p {
text-indent: 2em;
}
这会选择<article>
元素内的所有<p>
元素,无论它们是直接子元素还是更深层次的后代。
子选择器(>)
选择某个元素的直接子元素。
css
ul > li {
list-style-type: square;
}
这只会选择<ul>
的直接子元素<li>
,不会选择嵌套在更深层的<li>
元素。
相邻兄弟选择器(+)
选择紧接在某个元素后的兄弟元素。
css
h2 + p {
font-weight: bold;
}
这会选择紧跟在<h2>
元素后面的第一个<p>
元素。
通用兄弟选择器(~)
选择某个元素后的所有兄弟元素。
css
h2 ~ p {
color: #666;
}
这会选择与<h2>
元素同级的所有后续<p>
元素。
三、伪类选择器
伪类用于定义元素的特殊状态。(关于伪类的详情可以看我的《详解网页中薛定谔的状态:伪类》补补课)
链接和用户操作伪类
css
/* 未访问的链接 */
a:link {
color: blue;
}
/* 已访问的链接 */
a:visited {
color: purple;
}
/* 鼠标悬停状态 */
a:hover {
text-decoration: underline;
}
/* 激活状态(鼠标点击时) */
a:active {
color: red;
}
/* 获得焦点的元素 */
input:focus {
border-color: #007bff;
outline: none;
}
结构伪类
css
/* 第一个子元素 */
li:first-child {
font-weight: bold;
}
/* 最后一个子元素 */
li:last-child {
margin-bottom: 0;
}
/* 第n个子元素 */
li:nth-child(3) {
background-color: #f0f0f0;
}
/* 偶数位置的子元素 */
li:nth-child(even) {
background-color: #f9f9f9;
}
/* 奇数位置的子元素 */
li:nth-child(odd) {
background-color: #e9e9e9;
}
/* 使用公式:3n选择第3、6、9...个元素 */
li:nth-child(3n) {
border-bottom: 1px solid #ddd;
}
/* 第一个特定类型的元素 */
p:first-of-type {
font-size: 1.2em;
}
/* 最后一个特定类型的元素 */
p:last-of-type {
margin-bottom: 2em;
}
/* 第n个特定类型的元素 */
p:nth-of-type(2) {
font-style: italic;
}
其他常用伪类
css
/* 选择没有子元素的元素 */
.empty:empty {
display: none;
}
/* 选择被禁用的表单元素 */
input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}
/* 选择被选中的表单元素 */
input:checked + label {
font-weight: bold;
}
/* 选择必填的表单元素 */
input:required {
border-left: 4px solid red;
}
/* 选择有效的表单输入 */
input:valid {
border-color: green;
}
/* 选择无效的表单输入 */
input:invalid {
border-color: red;
}
四、伪元素选择器
伪元素用于创建不存在于DOM树中的元素。(关于伪元素的详情可以看我的《详解网页中的幽灵:伪元素》补补课)
css
/* 为元素的第一行添加样式 */
p::first-line {
font-weight: bold;
}
/* 为元素的第一个字母添加样式 */
p::first-letter {
font-size: 2em;
float: left;
margin-right: 5px;
}
/* 在元素内容之前插入内容 */
.quote::before {
content: """;
font-size: 2em;
color: #999;
}
/* 在元素内容之后插入内容 */
.quote::after {
content: """;
font-size: 2em;
color: #999;
}
/* 为选中的文本添加样式 */
::selection {
background-color: #ffeb3b;
color: #000;
}
五、选择器组合与优化
选择器分组
当多个选择器需要相同的样式时,可以使用逗号将它们分组。
css
h1, h2, h3, h4, h5, h6 {
font-family: 'Georgia', serif;
}
.btn-primary, .btn-secondary, .btn-danger {
border-radius: 4px;
padding: 8px 16px;
}
选择器优先级
CSS选择器的优先级按以下规则计算:
-
- 内联样式(1000分)
-
- ID选择器(100分)
-
- 类选择器、属性选择器和伪类(10分)
-
- 元素选择器和伪元素(1分)
css
/* 优先级: 1 */
p {
color: black;
}
/* 优先级: 10 */
.text {
color: blue;
}
/* 优先级: 100 */
#content {
color: red;
}
/* 优先级: 11 (10 + 1) */
.text p {
color: green;
}
/* 优先级: 111 (100 + 10 + 1) */
#content .text p {
color: purple;
}
!important
!important
规则可以覆盖任何其他样式声明,但应谨慎使用。
css
p {
color: red !important; /* 这将覆盖任何其他针对p元素的color属性 */
}
六、高级选择器技巧
:not() 伪类
:not()
伪类可以排除特定元素。
css
/* 选择所有不是.special类的段落 */
p:not(.special) {
color: #333;
}
/* 选择所有不是第一个子元素的列表项 */
li:not(:first-child) {
margin-top: 10px;
}
:is() 和 :where() 伪类
这些是较新的伪类,可以简化选择器列表。
css
/* 等同于 header p, main p, footer p */
:is(header, main, footer) p {
line-height: 1.6;
}
/* 与:is()类似,但优先级总是为0 */
:where(header, main, footer) p {
font-size: 16px;
}
自定义属性选择器匹配
属性选择器支持多种匹配模式:
css
/* 完全匹配 */
[data-type="primary"] {
background-color: blue;
}
/* 包含特定单词 */
[class~="btn"] {
padding: 5px 10px;
}
/* 以特定值开头(支持连字符) */
[lang|="en"] {
font-family: 'Arial', sans-serif;
}
/* 以特定字符串开头 */
[href^="https"] {
padding-right: 20px;
background: url('secure-icon.png') no-repeat right;
}
/* 以特定字符串结尾 */
[src$=".jpg"] {
border: 1px solid #ddd;
}
/* 包含特定字符串 */
[title*="example"] {
text-decoration: underline;
}
/* 大小写不敏感匹配(CSS4) */
[data-type="primary" i] {
color: white;
}
七、响应式设计中的选择器
在媒体查询中使用选择器可以创建响应式设计:
css
/* 在小屏幕上应用不同的样式 */
@media (max-width: 768px) {
.container {
width: 100%;
}
.sidebar {
display: none;
}
nav li {
display: block;
}
}
/* 在打印时应用特定样式 */
@media print {
nav, footer {
display: none;
}
article {
font-size: 12pt;
color: black;
}
a::after {
content: " (" attr(href) ")";
}
}
八、性能考虑
选择器的性能影响主要与浏览器的渲染机制有关。浏览器从右到左解析选择器。
-
考虑因素 :
- 避免过深的嵌套选择器
- 避免使用通用选择器作为关键选择器
- 尽量使用类选择器,而不是复杂的属性或后代选择器
- 减少选择器的数量和复杂度
-
示例 :
css/* 性能较差 */ body div ul li a { color: blue; } /* 性能较好 */ .nav-link { color: blue; }
九、实用选择器组合示例
表单样式
css
/* 所有必填字段添加红色星号 */
label.required::after {
content: " *";
color: red;
}
/* 无效输入显示红色边框 */
input:invalid {
border: 2px solid red;
}
/* 有效输入显示绿色边框 */
input:valid {
border: 2px solid green;
}
/* 禁用状态的按钮 */
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
导航菜单
css
/* 当前活动页面的导航项 */
nav a.active,
nav a[aria-current="page"] {
font-weight: bold;
border-bottom: 2px solid currentColor;
}
/* 鼠标悬停效果 */
nav a:hover {
background-color: rgba(0, 0, 0, 0.1);
}
/* 下拉菜单 */
.dropdown:hover .dropdown-menu {
display: block;
}
文章排版
css
/* 文章首字下沉效果 */
article p:first-of-type::first-letter {
font-size: 3em;
float: left;
line-height: 0.8;
margin-right: 8px;
color: #b30000;
}
/* 相邻标题之间增加间距 */
h2 + h3 {
margin-top: 0.5em;
}
/* 引用样式 */
blockquote {
border-left: 4px solid #ccc;
padding-left: 1em;
font-style: italic;
}
/* 列表样式 */
ul li:not(:last-child) {
margin-bottom: 0.5em;
}
结语
CSS选择器是前端开发的基础工具,掌握它们可以让你更精确地控制网页样式。从基础的元素、类和ID选择器,到高级的伪类、伪元素和属性选择器,每种选择器都有其特定的用途和优势。在实际开发中,应根据项目需求选择合适的选择器,并考虑可维护性和性能因素。通过组合使用不同类型的选择器,可以创建出既美观又高效的样式表。
随着CSS规范的不断发展,新的选择器和功能也在不断增加,持续学习和实践是保持技术更新的关键。希望这篇文章对你有所帮助,如果本文有错误,请你在评论区指出,大家一起进步,谢谢🙏。