10_03、CSS选择器
一、css简介
1、CSS是什么
CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素。
当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染)。
CSS3就是css语言,数字3是该语言的版本号
css语言开发的文件是以.css为后缀,通过在html文件中引入该css文件来控制html代码的样式(css语言代码也可以直接写在html文件中)
采用的语言是级联样式表 (Cascading Style Sheet),也属于标记语言。
2、CSS3语法
2.1 CSS语法实例
每个CSS样式由两个组成部分:选择器和声明。声明又包括属性和属性值。每个声明之后用分号结束。
2.2 CSS注释
/*这是注释*/
注释是代码之母。
3、css代码书写位置(引入方式)
css是来控制页面标签的样式,但是可以根据实际情况书写在不同的位置,放在不同位置有不同的专业叫法,可以分为行间式、内联式和外联式三种。
3-1 行间式
css样式书写在标签的style全局属性中,一条样式格式为 样式名: 样式值 单位;,可以同时出现多条样式
<!-- 关键代码 --> <!-- 给div标签设置宽高背景颜色 --> <div style="width: 200px; height: 200px; background-color: orange;"></div>
3-2 内联式
css样式书写在head标签内的style标签中,样式格式为 css选择器 { 样式块 },样式块由一条条样式组成
<!-- 关键代码 --> <head> <style> /* css语法下的注释语法 */ /* 设置页面中所有h2标签宽高背景颜色 */ h2 { width: 50px; height: 50px; background-color: orange; } /* 设置页面中所有h3标签宽高背景颜色 */ h3 { width: 100px; height: 100px; background-color: red; }
</style> </head> <body> <h2></h2> <h2></h2> <h3></h3> <h3></h3> </body>
3-3 外联式
css样式的写法同内联式,但样式书写在css文件中,在html页面中用link标签引入css文件(建议在head标签中引入)
- css文件夹下的my.css
/* html文件会引入该css文件,设置所有引入了html文件中的所有p标签宽高背景颜色 */ p { width: 50px; height: 50px; background-color: orange; }
- 根目录下的first.html
<!-- 关键代码 --> <head> <!-- rel="stylesheet":引入的是层级样式表,也就是css文件 type="text/css":引入文件采用的是css语法书写文本类型代码 href="css/my.css":采用相当路径引入目标css文件 --> <link rel="stylesheet" type="text/css" href="css/my.css"> </head> <body> <!-- 该页面中的p标签样式都被my.css文件控制 --> <p></p> <p></p> </body>
- 根目录下的second.html
<head> <link rel="stylesheet" type="text/css" href="css/my.css"> </head> <body> <!-- 该页面中的p标签样式也都被my.css文件控制 --> <p></p> <p></p> </body>
总结:
行间式控制样式最直接,但是样式多了直接导致页面可读性变差,且样式相同的标签样式也需要各自设置,复用性差;
内联式可以用一套样式块同时控制多个标签,具有样式的复用性,但是css样式代码还是写在html文件中,在项目开发下,代码量剧增,导致html文件变得臃肿,不利于代码维护;
外联式将css样式移到外部css文件中,不仅避免项目开发下html文件的臃肿问题,同时具有一套代码块控制多个标签,一个css样式文件服务于多个html两种复用性的好处,但是在学习阶段代码量不大时,样式不需要服务于多个html页面时,前面两种方式显然显得更便利。
在行间式中,写在标签内部的样式自然是用来控制该标签的样式,那写在内联式和外联式中的样式又是通过什么样的联系来控制对应页面中标签的样式呢?答案就是用于建立css与html之间联系的css选择器。
二、css选择器
css选择器本质就是css与html两种语法建立关联的特定标识符:
就是在css语法中,通过html中标签的某种名字,与html具体的标签建立关联,从而使写在对应css选择器后的css样式能控制html中关联的标签或标签们
而表示标签名字的方式有多种,每一种名字在css语法中都对应这一种特定标识符,下面我们就来详细介绍:
1、基础选择器
1-1 通配选择器
/* 特定标识符 星号(*) -- 可以表示页面所有标签的名字 */ /* 通配选择器控制页面中所有的标签(不建议使用) */ * { /* 样式块 */ } <!-- 页面中所有标签都能被匹配 --> <html></html> <body></body> <div></div> <p></p> <i></i>
1-2 标签选择器
/* 特定标识符 标签名 */ /* 标签选择器控制页面中标签名为标签选择器名的所有标签*/ div { /* 控制页面中所有div标签的样式 */ /* 样式块 */ } <!-- 页面中所有的div标签都能被匹配 --> <div></div> <div class="sup"> <div id='inner'></div> </div>
1-3 class选择器(提倡使用)
/* 特定标识符 点(.) */ /* class选择器控制页面中标签全局属性class值为class择器名的所有标签*/ .box { /* 控制页面中所有标签全局属性class值为box标签的样式 */ /* 样式块 */ } <!-- 页面中class属性值为box的标签都能被匹配 --> <div class="box"></div> <p class="box"> <i class="box"></i> </p>
1-4 id选择器
/* 特定标识符 井号(#) */ /* id选择器控制页面中标签全局属性id值为id择器名的唯一标签*/ #box { /* 控制页面中唯一标签全局属性id值为box标签的样式 */ /* 样式块 */ } <!-- 页面中id属性值为box的唯一标签备匹配,id具有唯一性:一个页面中所有标签的id属性值不能重名 --> <div id="box"></div>
1-5 基础选择器优先级
在一个页面中,难免会出现页面中的某一个标签的某一个样式被不同的选择器下的样式同时控制,也就是出现了多种方式下对目标标签的同一样式出现了重复控制,那到底是哪种选择器下的样式最终控制了目标标签,一定会有一套由弱到强的控制级别规则,这种规则就叫做优先级,下面的例子就很好的解释了各种基础选择器的优先级关系:
<head> <style> * { width: 50px; height: 50px; background-color: red; color: pink; } div { width: 60px; height: 60px; background-color: orange; } .box { width: 70px; height: 70px; } #ele { width: 80px; } </style> </head> <body> <div class="box" id="ele">文字内容</div> </body> <!-- 1. 四种选择器都控制目标标签的宽度,最终目标标签宽度为80px,所以id选择器优先级最高 2. 三种选择器都控制目标标签的高度,最终目标标签宽度为70px,所以class选择器优先级其次 3. 二种选择器都控制目标标签的背景颜色,最终目标标签背景颜色为orange,所以标签选择器优先级再次 4. 只有一种选择器控制目标标签的字体颜色,目标标签字体颜色一定为pink
总结: 优先级:通配选择器 < 标签选择器 < class选择器 < id选择器 -->
1-6 案例

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> /*id选择器*/ /*#d1 { !*找到id是d1的标签 将文本颜色变成绿黄色*!*/ /* color: greenyellow;*/ /*}*/ /*类选择器*/ /*.c1 { !*找到class值里面包含c1的标签*!*/ /* color: red;*/ /*}*/ /*元素(标签)选择器*/ /*span { !*找到所有的span标签*!*/ /* color: red;*/ /*}*/ /*通用选择器*/ /** { !*将html页面上所有的标签全部找到*!*/ /* color: green;*/ /*}*/ </style> </head> <body> <div id="d1" class="c1 c2">div <p>div里面的p</p> <span>div里面的span</span> </div> <p id="d2" class="c1 c2">ppp</p> <span id="d3" class="c2">span111</span> <span id="d4" class="c3">span222</span> </body> </html>
2、复杂选择器(了解即可)
2-1 群组选择器
/* 连接标识符 逗号(,) */ /* 群组选择器就是一套样式块同时控制用逗号连接(,)的所有目标标签 */ div, p, .box, #ele { /* 样式块 */ } <!-- 页面中所有div标签、所有p标签、所有class属性值为box、唯一id属性值为ele的标签都能被匹配 --> <div> <div></div> </div> <p></p> <p></p> <i class="box"></i> <span class="box"></span> <b id="ele"></b>
2-2 后代选择器
/* 连接标识符 空格( ) */ /* 后代选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */ body .box i { /*最后置位的选择器为i标签选择器,前置位body标签选择器、class值为box的class选择器都是修饰*/ /* 样式块 */ } <!-- body标签内部的class属性值为box内部的i标签们都能被匹配,所以只匹配i标签,其他都是修饰 --> <body> <div class='box'> <span><i></i></span><!-- body与.box是直接父子关系,.box与i是间接父子关系,能被匹配 --> </div> <div> <span class='box'><i></i></span><!-- body与.box是间接父子关系,.box与i是直接父子关系,能被匹配 --> </div> </body> <!-- 标签的嵌套结构形成父子代标签,后代选择器可以匹配直接父子关系或间距父子关系形成的层次,所以两个i标签均能被匹配 -->
2-3 子代选择器(儿子选择器)
/* 连接标识符 大于号(>) */ /* 子代选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */ body>.box>i { /*最后置位的选择器为i标签选择器,前置位body标签选择器、class值为box的class选择器都是修饰*/ /* 样式块 */ } <!-- body>.box>i:同理body和.box都是修饰位,i才是目标匹配位 --> <body> <div class='box'> <span><i></i></span><!-- body与.box是直接父子关系,.box与i是间接父子关系,不能被匹配 --> </div> <div> <span class='box'><i></i></span><!-- body与.box是间接父子关系,.box与i是直接父子关系,不能被匹配 --> </div> <div class='box'> <i></i><!-- body与.box是直接父子关系,.box与i是直接父子关系,能被匹配 --> </div> </body> <!-- 子代选择器只能匹配直接父子关系,所以只能匹配最后一个i标签 -->
2-4 兄弟选择器
/* 连接标识符 波浪号(~) */ /* 兄弟选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */ #ele~div~i { /*最后置位的选择器为i标签选择器,前置位id值为ele的id选择器、div标签选择器都是修饰*/ /* 样式块 */ } <!-- #ele~div~i:同理#ele和div都是修饰位,i才是目标匹配位 --> <h3 id="ele"></h3> <div></div><!-- #ele与div是直接兄弟关系 --> <i></i><!-- div与i是直接兄弟关系,能被匹配 --> <div></div><!-- #ele与div是间距兄弟关系 --> <i></i><!-- div与i是直接兄弟关系,能被匹配 --> <!-- 标签的上下结构形成兄弟标签,兄弟选择器可以匹配直接兄弟关系或间距兄弟关系形成的层次,所以两个i标签均能被匹配 -->
2-5 相邻选择器(毗邻选择器)
/* 连接标识符 加号(+) */ /* 相邻选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */ #ele+div+i { /*最后置位的选择器为i标签选择器,前置位id值为ele的id选择器、div标签选择器都是修饰*/ /* 样式块 */ } <!-- #ele+div+i:同理#ele和div都是修饰位,i才是目标匹配位 --> <h3 id="ele"></h3> <div></div><!-- #ele与div是直接兄弟关系 --> <i></i><!-- div与i是直接兄弟关系,能被匹配 --> <div></div><!-- #ele与div是间距兄弟关系 --> <i></i><!-- div与i是直接兄弟关系,不能被匹配 --> <!-- 相邻选择器只能匹配直接兄弟关系,所以只能匹配第一个i标签 -->
2-6 交叉选择器
/* 连接标识符 紧挨着(没有任何连接符) */ /* 交叉选择器本质上是对一个目标标签的多个名字的同时表示 */ div.box#ele.tag { /*div是标签名,box和tag都是class属性值,ele是id属性值*/ /* 样式块 */ } <!-- 标签名div、class名box及tag和id名ele都是对一个目标标签的修饰空格隔开 <!-- class属性拥有多个值时,多个值之间用空格隔开 --> <div class="box tag" id="ele"></div>
2-7 属性选择器
/*用于选取带有指定属性的元素。*/
p[title] {
color: red;
}
/*用于选取带有指定属性和值的元素。*/
p[title="213"] {
color: green;
}
2-8 基础选择器优先级
简单选择器存在优先级,优先级的前提就是不同选择器同时控制同一标签的同一属性,那么在复杂选择器下,一定会出现这种同时控制同一标签的同一属性情况,那复杂选择器的优先级又是如何来规定的呢?
1. 复杂选择器的种类并不会影响优先级
-- 后代:div #ele | 兄弟:div~#ele | 交叉:div#ele 优先级一样
2. 复杂选择器本质是通过同类型(简单选择器)的个数来确定优先级
-- 三层标签选择器后代:body div i 大于 两层标签选择器后代:div i | body i
3. 简单选择器的优先级起关键性作用,也就是一个id选择器要大于无限个class选择器,一个class选择器要大于无限个标签选择器
-- id选择器:#i 大于 n层class选择器:.box .i
-- class选择器:.box 大于 n层标签选择器:body div
3 分组和嵌套
3-1 分组(了解即可)
当多个元素的样式相同的时候,我们没有必要重复地为每个元素都设置样式,我们可以通过在多个选择器之间使用逗号分隔的分组选择器来统一设置元素样式。
div, p {
color: red;
}
上面的代码为div标签和p标签统一设置字体为红色。
通常,我们会分两行来写,更清晰:
div,
p {
color: red;
}
3-2 嵌套
多种选择器可以混合起来使用
比如:.c1类内部所有p标签设置字体颜色为红色。
.c1 p {
color: red;
}
4 伪类选择器(*****)
/* 未访问的链接 */ a:link { color: #FF0000 } /* 鼠标移动到链接上 */ a:hover { color: #FF00FF } /* 选定的链接 */ a:active { color: #0000FF } /* 已访问的链接 */ a:visited { color: #00FF00 } /*input输入框获取焦点时样式*/ input:focus { outline: none; background-color: #eee; }
案例

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { background-color: black; } a:link { /*访问之前的状态*/ color: red; } a:hover { /*需要记住*/ color: aqua; /*鼠标悬浮态*/ } a:active { color: black; /*鼠标点击不松开的状态 激活态*/ } a:visited { color: darkgray; /*访问之后的状态*/ } p { color: darkgray; font-size: 48px; } p:hover { color: white; } input:focus { /*input框获取焦点(鼠标点了input框)*/ background-color: red; } </style> </head> <body> <a href="https://www.jd.com/">小轩在不在?</a> <p>点我有你好看哦</p> <input type="text"> </body> </html>
5 伪元素选择器
5-1 first-letter
常用的给首字母设置特殊样式:
p:first-letter { font-size: 48px; color: red; }
5-2 before
/*在每个<p>元素之前插入内容*/ p:before { content:"*"; color:red; }
5-3 after
/*在每个<p>元素之后插入内容*/ p:after { content:"[?]"; color:blue; }
before和after多用于清除浮动。
5-4 案例

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> p:first-letter { font-size: 48px; color: orange; } p:before { /*在文本开头 同css添加内容*/ content: '你说的对'; color: blue; } p:after { content: '雨露均沾'; color: orange; } </style> </head> <body> <p>装备差进任何本都是血赚,装备差进任何本都是血赚</p> </body> </html>
6、选择器优先级
6-1 CSS继承
继承是CSS的一个主要特征,它是依赖于祖先-后代的关系的。继承是一种机制,它允许样式不仅可以应用于某个特定的元素,还可以应用于它的后代。
例如一个body定义了的字体颜色值也会应用到段落的文本中。
body { color: red; }
此时页面上所有标签都会继承body的字体颜色。然而CSS继承性的权重是非常低的,是比普通元素的权重还要低
我们只要给对应的标签设置字体颜色就可覆盖掉它继承的样式。
p { color: green; }
此外,继承是CSS重要的一部分,我们甚至不用去考虑它为什么能够这样,但CSS继承也是有限制的。有一些属性不能被继承,如:border, margin, padding, background等。
6-2 选择器的优先级
我们上面学了很多的选择器,也就是说在一个HTML页面中有很多种方式找到一个元素并且为其设置样式,那浏览器根据什么来决定应该应用哪个样式呢?
其实是按照不同选择器的权重来决定的,具体的选择器权重计算方式如下图:
除此之外还可以通过添加 !important方式来强制让样式生效,但并不推荐使用。因为如果过多的使用!important会使样式文件混乱不易维护。
万不得已可以使用!important
body { color : red !important; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!