Justin-刘清政的博客

python/前端/4-CSS3选择器

2020-11-03

css选择器

css选择器本质就是css与html两种语法建立关联的特定标识符:

就是在css语法中,通过html中标签的某种名字,与html具体的标签建立关联,从而使写在对应css选择器后的css样式能控制html中关联的标签或标签们

而表示标签名字的方式有多种,每一种名字在css语法中都对应这一种特定标识符,下面我们就来详细介绍:

1、基础选择器

1-1 通配选择器

1
2
3
4
5
6
7
8
9
10
11
/* 特定标识符 星号(*) -- 可以表示页面所有标签的名字 */
/* 通配选择器控制页面中所有的标签(不建议使用) */
* {
/* 样式块 */
}
<!-- 页面中所有标签都能被匹配 -->
<html></html>
<body></body>
<div></div>
<p></p>
<i></i>

1-2 标签选择器

1
2
3
4
5
6
7
8
9
10
/* 特定标识符 标签名 */
/* 标签选择器控制页面中标签名为标签选择器名的所有标签*/
div { /* 控制页面中所有div标签的样式 */
/* 样式块 */
}
<!-- 页面中所有的div标签都能被匹配 -->
<div></div>
<div class="sup">
<div id='inner'></div>
</div>

1-3 class选择器(提倡使用)

1
2
3
4
5
6
7
8
9
10
/* 特定标识符 点(.) */
/* class选择器控制页面中标签全局属性class值为class择器名的所有标签*/
.box { /* 控制页面中所有标签全局属性class值为box标签的样式 */
/* 样式块 */
}
<!-- 页面中class属性值为box的标签都能被匹配 -->
<div class="box"></div>
<p class="box">
<i class="box"></i>
</p>

1-4 id选择器

1
2
3
4
5
6
7
/* 特定标识符 井号(#) */
/* id选择器控制页面中标签全局属性id值为id择器名的唯一标签*/
#box { /* 控制页面中唯一标签全局属性id值为box标签的样式 */
/* 样式块 */
}
<!-- 页面中id属性值为box的唯一标签备匹配,id具有唯一性:一个页面中所有标签的id属性值不能重名 -->
<div id="box"></div>

1-5 基础选择器优先级

在一个页面中,难免会出现页面中的某一个标签的某一个样式被不同的选择器下的样式同时控制,也就是出现了多种方式下对目标标签的同一样式出现了重复控制,那到底是哪种选择器下的样式最终控制了目标标签,一定会有一套由弱到强的控制级别规则,这种规则就叫做优先级,下面的例子就很好的解释了各种基础选择器的优先级关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<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 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!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 群组选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 连接标识符 逗号(,) */
/* 群组选择器就是一套样式块同时控制用逗号连接(,)的所有目标标签 */
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 后代选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 连接标识符 空格( ) */
/* 后代选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */
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 子代选择器(儿子选择器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 连接标识符 大于号(>) */
/* 子代选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */
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 兄弟选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 连接标识符 波浪号(~) */
/* 兄弟选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */
#ele~div~i {
/*最后置位的选择器为i标签选择器,前置位id值为ele的id选择器、div标签选择器都是修饰*/
/* 样式块 */
}
<!-- #ele~div~i:同理#elediv都是修饰位,i才是目标匹配位 -->
<h3 id="ele"></h3>
<div></div><!-- #ele与div是直接兄弟关系 -->
<i></i><!-- div与i是直接兄弟关系,能被匹配 -->
<div></div><!-- #ele与div是间距兄弟关系 -->
<i></i><!-- div与i是直接兄弟关系,能被匹配 -->
<!-- 标签的上下结构形成兄弟标签,兄弟选择器可以匹配直接兄弟关系或间距兄弟关系形成的层次,所以两个i标签均能被匹配 -->

2-5 相邻选择器(毗邻选择器)

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 连接标识符 加号(+) */
/* 相邻选择器控制的是最后置的选择器位匹配到目标标签(们),前置位的所有选择器都是修饰 */
#ele+div+i {
/*最后置位的选择器为i标签选择器,前置位id值为ele的id选择器、div标签选择器都是修饰*/
/* 样式块 */
}
<!-- #ele+div+i:同理#elediv都是修饰位,i才是目标匹配位 -->
<h3 id="ele"></h3>
<div></div><!-- #ele与div是直接兄弟关系 -->
<i></i><!-- div与i是直接兄弟关系,能被匹配 -->
<div></div><!-- #ele与div是间距兄弟关系 -->
<i></i><!-- div与i是直接兄弟关系,不能被匹配 -->
<!-- 相邻选择器只能匹配直接兄弟关系,所以只能匹配第一个i标签 -->

2-6 交叉选择器

1
2
3
4
5
6
7
8
9
/* 连接标识符 紧挨着(没有任何连接符) */
/* 交叉选择器本质上是对一个目标标签的多个名字的同时表示 */
div.box#ele.tag {
/*div是标签名,box和tag都是class属性值,ele是id属性值*/
/* 样式块 */
}
<!-- 标签名divclassboxtagidele都是对一个目标标签的修饰空格隔开
<!-- class属性拥有多个值时,多个值之间用空格隔开 -->
<div class="box tag" id="ele"></div>

2-7 属性选择器

1
2
3
4
5
6
7
8
/*用于选取带有指定属性的元素。*/
p[title] {
color: red;
}
/*用于选取带有指定属性和值的元素。*/
p[title="213"] {
color: green;
}

不怎么常用的属性选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*找到所有title属性以hello开头的元素*/
[title^="hello"] {
color: red;
}

/*找到所有title属性以hello结尾的元素*/
[title$="hello"] {
color: yellow;
}

/*找到所有title属性中包含(字符串包含)hello的元素*/
[title*="hello"] {
color: red;
}

/*找到所有title属性(有多个值或值以空格分割)中有一个值为hello的元素:*/
[title~="hello"] {
color: green;

2-7 基础选择器优先级

简单选择器存在优先级,优先级的前提就是不同选择器同时控制同一标签的同一属性,那么在复杂选择器下,一定会出现这种同时控制同一标签的同一属性情况,那复杂选择器的优先级又是如何来规定的呢?

1
2
3
4
5
6
7
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

2-8 案例一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/*后代选择器*/
/*div span {*/
/* color: red;*/
/*}*/

/*儿子选择器*/
/*div>span {*/
/* color: red;*/
/*}*/

/*毗邻选择器*/
/*div+span { !*同级别紧挨着的下面的第一个*!*/
/* color: aqua;*/
/*}*/

/*弟弟选择器*/
div~span { /*同级别下面所有的span*/
color: red;
}
</style>
</head>
<body>
<span>span1</span>
<span>span2</span>
<div>div
<p>div p</p>
<p>div p
<span>div p span</span>
</p>
<span>span</span>
<span>span</span>
</div>
<span>span</span>
<span>span</span>
<p>ppp</p>
<span>span</span>
</body>
</html>

2-9 案例二(属性选择器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>

/*[username] { !*将所有含有属性名是username的标签背景色改为红色*!*/
/* background-color: red;*/
/*}*/

/*[username='jason'] { !*找到所有属性名是username并且属性值是jason的标签*!*/
/* background-color: orange;*/
/*}*/

/*input[username='jason'] { !*找到所有属性名是username并且属性值是jason的input标签*!*/
/* background-color: wheat;*/
/*}*/
</style>
</head>
<body>
<input type="text" username>
<input type="text" username="jason">
<input type="text" username="kevin">
<p username="tank">水箱老师</p>
<div username="egon">矮子老师</div>
<span username="jason">jason老师 </span>
</body>
</html>

2-10 案例三(输入框默认提示)

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="text" placeholder="用户名">
<p id="d1" class="c1"></p>

</body>
</html>

3 分组和嵌套

31 分组

当多个元素的样式相同的时候,我们没有必要重复地为每个元素都设置样式,我们可以通过在多个选择器之间使用逗号分隔的分组选择器来统一设置元素样式。

例如:

1
2
3
div, p {
color: red;
}

上面的代码为div标签和p标签统一设置字体为红色。

通常,我们会分两行来写,更清晰:

1
2
3
4
div,
p {
color: red;
}

3-2 嵌套

多种选择器可以混合起来使用,比如:.c1类内部所有p标签设置字体颜色为红色。

1
2
3
.c1 p {
color: red;
}

3-3 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style>
/*div {*/
/* color: red;*/
/*}*/
/*p {*/
/* color: red;*/
/*}*/
/*span {*/
/* color: red;*/
/*}*/
div,p,span { /*逗号表示并列关系*/
color: yellow;
}
#d1,.c1,span {
color: orange;
}
#d1 .c2 span{
color: red;
}
</style>
</head>
<body>
<div id="d1">div
<p class="c2">div>p
<span id="d3">div>p>span1</span>
<span id="d4">div>p>span2</span>
</p>
<p class="c3">
sadjasdjkasldj
</p>
</div>
<p class="c1">p</p>
<span>span</span>
</body>
</html>

4 伪类选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* 未访问的链接 */
a:link {
color: #FF0000
}

/* 鼠标移动到链接上 */
a:hover {
color: #FF00FF
}

/* 选定的链接 */
a:active {
color: #0000FF
}

/* 已访问的链接 */
a:visited {
color: #00FF00
}

/*input输入框获取焦点时样式*/
input:focus {
outline: none;
background-color: #eee;
}

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!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

常用的给首字母设置特殊样式:

1
2
3
4
p:first-letter {
font-size: 48px;
color: red;
}

5-2 before

1
2
3
4
5
/*在每个<p>元素之前插入内容*/
p:before {
content:"*";
color:red;
}

5-3 after

1
2
3
4
5
/*在每个<p>元素之后插入内容*/
p:after {
content:"[?]";
color:blue;
}

before和after多用于清除浮动。

5-4 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!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定义了的字体颜色值也会应用到段落的文本中。

1
2
3
body {
color: red;
}

此时页面上所有标签都会继承body的字体颜色。然而CSS继承性的权重是非常低的,是比普通元素的权重还要低的0。

我们只要给对应的标签设置字体颜色就可覆盖掉它继承的样式。

1
2
3
p {
color: green;
}

此外,继承是CSS重要的一部分,我们甚至不用去考虑它为什么能够这样,但CSS继承也是有限制的。有一些属性不能被继承,如:border, margin, padding, background等。

6-2 选择器的优先级

我们上面学了很多的选择器,也就是说在一个HTML页面中有很多种方式找到一个元素并且为其设置样式,那浏览器根据什么来决定应该应用哪个样式呢?

其实是按照不同选择器的权重来决定的,具体的选择器权重计算方式如下图:

img

除此之外还可以通过添加 !important方式来强制让样式生效,但并不推荐使用。因为如果过多的使用!important会使样式文件混乱不易维护。

万不得已可以使用!important

1
2
3
body {
color : red !important;
}

6-3 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<style>
/*
1.选择器相同 书写顺序不同
就近原则:谁离标签更近就听谁的
2.选择器不同 ...
行内 > id选择器 > 类选择器 > 标签选择器
精确度越高越有效
*/
#d1 {
color: aqua;
}
/*.c1 {*/
/* color: orange;*/
/*}*/
/*p {*/
/* color: red;*/
/*}*/
</style>
<!-- <link rel="stylesheet" href="mycss1.css">-->
</head>
<body>
<p id="d1" class="c1" style="color: blue">贤妻果然很识趣,有前途~</p>
</body>
</html>

mycss1.css

1
2
3
p {
color: greenyellow;
}
使用支付宝打赏
使用微信打赏

点击上方按钮,请我喝杯咖啡!

扫描二维码,分享此文章