开发中经常需要找到特定的网页元素进行设置样式
所以我们需要按照一定的规则选出符合条件的元素,为之添加CSS样式
而这些规则就被称之为CSS选择器
通用选择器
通用选择器(universal selector) --- 所有的元素都会被选中
一般用来给所有元素作一些通用性的设置 --- 例如清除body默认的8px外边距
/*
一般不建议为元素添加对应的通用选择器
因为浏览器在使用通配符选择器为元素添加对应样式的时候
会遍历所有的元素,并为每一个元素应用上对应的样式,包括html元素和body元素
有很多元素我们其实是没有使用的,但是通配符选择器还是会为他们添加对应的样式
所以使用通配符选择器的效率比较低
*/
* {
margin: 0;
padding: 0;
}
/*
如果我们需要重置某些元素的样式的时候,
推荐显示的将我们所用到的元素逐个进行对应的清除
或者使用normalize.css这类第三方库
*/
div,
p,
ul,
li {
margin: 0;
padding: 0;
}
元素选择器
元素选择器(type selectors), 使用元素的名称, 会匹配到所有符合对应元素名的元素
div {
border: 1px solid red;
}
类选择器
.box {
color: red;
}
可以在一个元素上添加多个类,类和类之间使用空格进行划分
<div class="foo baz bar"> Delectus reiciendis in fuga repellat reprehenderit optio, facere </div>
id选择器
#box {
color: red;
}
Tips: 对于类选择器和id选择器
一个HTML文档里面的id值是唯一的,不能重复 --- 重复不报错 是因为浏览器做了容错处理,不推荐
不要用标签名作为id值或者类名 --- 不会报错,不推荐,可读性差
id选择器名或class选择器类型如果由多个单词组成,单词之间可以用
中划线-
、下划线_
连接,也可以使用驼峰标识(包括大驼峰和小驼峰)
- 中划线又叫连字符(hyphen)
- 推荐使用中划线进行多个单词之间的连接符
属性选择器
/* 只要有属性title的元素,字体全部被设置为红色 */
[title] {
color: red;
}
CSS选择器中的属性选择器可以根据元素的属性和值来选择元素。具体来说:
-
如果属性值是简单的单个单词,比如
lorem
,引号是可以省略的。例如:[title=lorem] { color: red; }
-
如果属性值是复杂的,比如包含空格的字符串
lorem lorem
,引号是不可以省略的。例如:[title='lorem lorem'] { color: red; }
一些其它用法
-
选择器
[class*=box]
:-
选择所有
class
属性值中包含box
的元素。 -
示例:
<div class="dv box"></div> <!-- 符合 --> <div class="dv box1"></div> <!-- 符合 --> <div class="dv-box"></div> <!-- 符合 -->
-
-
选择器
[class^=box]
:-
选择所有
class
属性值以box
开头的元素。 -
示例:
<div class="box"></div> <!-- 符合 --> <div class="box1"></div> <!-- 符合 --> <div class="box-dv"></div> <!-- 符合 -->
-
-
选择器
[class$=box]
:-
选择所有
class
属性值以box
结尾的元素。 -
示例:
<div class="dv box"></div> <!-- 符合 --> <div class="box"></div> <!-- 符合 --> <div class="dv-box"></div> <!-- 符合 -->
-
-
选择器
[class|=dv]
:-
选择所有
class
属性值等于dv
或以dv-
开头的元素。 -
示例:
<div class="dv"></div> <!-- 符合 --> <div class="dv-box"></div> <!-- 符合 --> <div class="dv-box1"></div> <!-- 符合 -->
-
-
选择器
[class~=dv]
:-
选择所有
class
属性值包含dv
,且dv
作为独立的值存在(即class
是由空格分割的多个值的列表,其中一个值必须是dv
)。 -
示例:
<div class="dv box"></div> <!-- 符合 --> <div class="box dv"></div> <!-- 符合 --> <div class="dv-box"></div> <!-- 不符合 -->
-
后代选择器
后代元素 = 直接后代元素 + 间接后代元素
一般后代表示的就是直接后代元素 + 间接后代元素
而子代表示的就是直接子代元素
所有后代选择器
选择器之间以空格分割
/*
.dv元素下 所有有foo class样式的 后代元素
*/
.dv .foo {
color: red;
}
直接子代选择器
/*
.dv元素下 所有有foo class样式的 直接后代元素(直接子代元素)
*/
.dv > .foo {
color: red;
}
兄弟选择器
注意: 在默认情况下,兄弟选择器选中的都是后继兄弟元素
如果需要选中前置兄弟元素,可以结合
:not
伪元素来进行选择
相邻兄弟选择器
- 使用符号 + 连接
/*
有lorem类的元素 后边的第一个兄弟层级的div元素
*/
.lorem + div {
color: red;
}
全兄弟选择器
- 使用符号 ~ 连接
/*
有lorem类的元素 后边的所有的兄弟层级的div元素 (不包括前边的)
*/
.lorem ~ div {
color: red;
}
选择器组
交集选择器:
交集选择器 --- 需要同时符合两个选择器条件 (两个选择器紧密连接)
/*
有lorem类的div元素 --- 两者必须同时满足
*/
div.lorem {
color: red;
}
并集选择器:
并集选择器 --- 符合一个选择器条件即可 (两个选择器以,号分割)
/*
1. 有lorem类的元素或者div元素 --- 多个条件之间满足其中任意一个即可
2. 多个条件之间使用逗号进行分割,且推荐每个条件都用新的一行进行表示
*/
.lorem,
div {
color: red;
}
伪类选择器
Pseudo-classes: 翻译过来是伪类
伪类是选择器的一种,它用于选择处于特定状态的元素
--- 如被点击,被悬浮等
常见伪类分类 | 举例 |
---|---|
动态伪类 | :link、:visited、:hover、:active、:focus |
目标伪类 | :target |
语言伪类 | :lang( ) |
元素状态伪类 | :enabled、:disabled、:checked、:selected |
结构伪类 | :nth-child( )、:nth-last-child( )、:nth-of-type( )、:nth-last-of-type( ) :first-child、:last-child、:first-of-type、:last-of-type :root、:only-child、:only-of-type、:empty |
否定伪类 | :not() |
其它 | :placeholder |
动态伪类
a:link
未访问的链接a:visited
已访问的链接a:hover
鼠标挪动到链接上a:active
激活的链接(鼠标在链接上长按住未松开):focus
指当前拥有输入焦点的元素
除了
a
元素,:hover, :active
也能用在其他元素上直接给a元素设置样式,相当于给a元素的所有动态伪类都设置了
--- 相当于
a:link、a:visited、a:hover、a:active、a:focus
都设置了相同的样式因为链接a元素可以被键盘的
Tab键
选中聚焦,所以:focus
也适用于a
元素
a:link {
color: red;
}
a:visited {
color: green;
}
/*
当a链接被点击了以后
a链接其实即处于focus状态 也处于active状态
所以为了确保active状态的样式不被覆盖
active伪类 推荐 放置到 focus伪类后进行编写
*/
a:focus {
color: gray;
}
a:hover {
color: blue;
}
a:active {
color: orange;
}
/*
a {
color: paleturquoise;
}
*/
注意:
:hover
必须放在:link
和:visited
后面才能完全生效:active
必须放在:hover
后面才能完全生效:focus
必须放在:hover
后,:active
之前才能完全生效
所以动态伪类编写顺序推荐为: :link、:visited、:focus、:hover、:active
目标伪类 --- :target
:target 用于匹配那个元素的id属性的值 和 url中的fragment字段的值一致
:target {
color: red;
}
<div id="foo">foo</div>
<div id="bar">bar</div>
<div id="baz">baz</div>
在本例中, 当URL为http://www.example.com/index.html#bar
时 <div id="bar">bar</div>
的颜色会被设置为红色
语言伪类 --- :lang()
-
lang
属性是一个全局属性,可以在任何 HTML 元素上设置。它用于指定元素内容的语言。
一般设置于html元素上,以便于全局生效。
-
:lang
伪类选择器用于选择具有特定语言属性的元素。它的语法是
:lang(language)
,其中language
是一个语言代码。 -
在
:lang
伪类选择器中,语言代码不需要加引号。因为其本质是语言代码,不是字符串
<div lang="zh-CN">foo</div>
:lang(zh)
选择器会匹配 lang
属性值以 zh
开头的所有元素,包括 zh-CN
、zh-TW
等。
:lang(zh) {
color: red;
}
结构伪类
选择器 | 作用 |
---|---|
:nth-child(n) | css函数调用 n的其值从0开始依次递增 选取当前元素的父元素的第n个子元素 |
:nth-last-child(n) | css函数调用 n的其值从0开始依次递增 从后往前选取当前元素的父元素的第n个子元素 |
:nth-of-type(n) | css函数调用 n的其值从0开始依次递增 选取当前元素的父元素的第n个同类型子元素 |
:nth-last-of-type(n) | css函数调用 n的其值从0开始依次递增 从后往前选取当前元素的父元素的第n个同类型子元素 |
:first-child | 等同于:nth-child(1) |
:last-child | 等同于:nth-last-child(1) |
:first-of-type | 等同于:nth-of-type(1) |
:last-of-type | 等同于:nth-last-of-type(1) |
:only-child | 该元素是父元素中唯一的子元素 即匹配没有任何兄弟元素的元素 |
:only-of-type | 该元素是父元素中唯一的同类型子元素 即该子元素在父元素中没有其它相同类型的兄弟元素 |
:root | 根元素,就是HTML元素 |
:empty | 完全空白的元素 |
:nth-child
vs :nth-of-type
<!-- :nth-child(n) -->
<style>
/* ul下的第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色 */
/*
注意:在JS中 索引是从0开始计算的,但是在css中,索引是从1开始计算的
也就是说nth-child(3) 选择的是第三个对应的元素
*/
ul :nth-child(3) {
color: red;
}
</style>
<ul>
<li>content1</li>
<li>content2</li>
<!-- content3的颜色被设置成了红色 -->
<li>content3</li>
<li>content4</li>
<li>content5</li>
</ul>
<!-- :nth-last-child(n) -->
<style>
/* ul下的倒数第二个子元素,且该子元素的类型是li的时候,设置其颜色为红色 */
ul li:nth-last-child(2) {
color: red;
}
</style>
<ul>
<li>content1</li>
<li>content2</li>
<li>content3</li>
<!-- content4的颜色被设置成了红色 -->
<li>content4</li>
<li>content5</li>
</ul>
<!-- :nth-of-type(n) -->
<style>
/*
ul下的第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色
在计算过程中,不计算其它类型元素
*/
ul li:nth-of-type(3) {
color: red;
}
</style>
<ul>
<li>content1</li>
<li>content2</li>
<span>span 1</span>
<!-- content3的颜色被设置成了红色 -->
<li>content3</li>
<li>content4</li>
<li>content5</li>
</ul>
<!-- :nth-last-of-type(n) -->
<style>
/*
ul下的倒数第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色
在计算过程中,不计算其它类型元素
*/
ul li:nth-last-of-type(3) {
color: red;
}
</style>
<ul>
<li>content1</li>
<li>content2</li>
<!-- content3的颜色被设置成了红色 -->
<li>content3</li>
<span>span 1</span>
<li>content4</li>
<li>content5</li>
</ul>
:nth-child(n)
的其它使用方式
:nth-child(n)
的其它使用方式同样使用于:nth-last-child(n)
,:nth-of-type(n)
和:nth-last-of-type(n)
/*
选中所有的偶数列
:nth-child(2n) 等价于 :nth-child(even)
*/
ul li:nth-child(2n) {
color: red;
}
/*
选中所有的偶数列
:nth-child(2n + 1) 等价于 :nth-child(odd) 等价于 :nth-child(2n - 1)
*/
ul li:nth-child(2n + 1) {
color: red;
}
/*
选中第一个子元素
:nth-child(1) 等价于 :first-child
*/
ul li:nth-child(1) {
color: red;
}
/*
-n + X
选中前X个子元素
*/
ul li:nth-child(-n + 3) {
color: red;
}
/*
设置第一个,第五个,第九个,第十三个 ... 子元素的字体颜色为红色
*/
ul li:nth-child(4n + 1) {
color: red;
}
否定伪类 --- :not()
:not(x)
--- x是一个简单选择器, 可以是元素选择器、通用选择器、属性选择器、类选择器、id选择器、伪类(除否定伪类)等任何合法的选择器
在设置:not(x)
的时候,一般会添加一个限制条件, 例如xxxx :not(x)
, 从而避免将样式添加到body
或html
等元素上
/* .dv元素下 没有.lorem 这样一个类的元素 */
.dv :not(.lorem){
color: red;
}
:is()
:is
选择器用于减少冗长的选择器列表。它接受一个选择器列表,并匹配其中的任何一个选择器
:is(.class1, .class2, .class3) > p {
color: red;
}
等价于
.class1 > p,
.class2 > p,
.class3 > p {
color: red;
}
:is
选择器的特异性由其包含的选择器中特异性最高的那个决定
:is(#id, .class, article) {
margin: 20px;
}
#id
的特异性是 0100.class
的特异性是 0010article
的特异性是 0001
在这种情况下,:is(#id, .class, article)
的特异性将是 0100,因为 #id
的特异性最高。
:where()
:where
选择器的功能与 :is
类似,但它具有一个重要的区别::where
选择器的特异性(specificity,也就是选择器的优先级)始终为零。这意味着它不会影响选择器的优先级。
article {
margin: 10px;
}
:where(article, section, aside) {
margin: 20px;
}
因为:where
中的选择器优先级为0,所以article
元素的边框值是10px
/* article 的特异性是 0001 */
article {
margin: 10px;
}
/* :is(article, section, aside) 的特异性是 0001 */
:is(article, section, aside) {
margin: 20px;
}
最终,article
元素的边框值是20px
:has()
A:has(B)
选择的是那些包含至少一个 B 元素的 A 元素。然后,你可以对这些 A 元素应用相应的样式
:has()
是一个相对较新的 CSS 选择器, 浏览器支持情况可能不太理想
<!-- .container背景会变黄 -->
<div class="container">
<p>Paragraph 1</p>
<span>Span 1</span>
</div>
<!-- .container背景不会变黄 -->
<div class="container">
<p>Paragraph 2</p>
</div>
<style>
.container:has(span) {
background-color: yellow;
}
</style>
/* 选择包含 <p>、<span> 或 <h3> 元素中的任意一个的 .box 元素 */
.box:has(p, span, h3) {
display: none;
}
<style>
/*
找到div元素,且该元素后边的直接兄弟元素有.lorem
所以其本质就是找有.lorem类的前一个div元素
*/
div:has(+ .lorem) {
color: red;
}
</style>
<div>lorem</div>
<div class="lorem">lorem</div>
伪元素
常用的伪元素有
- :first-line、::first-line
- :first-letter、::first-letter
- :before、::before
- :after、::after
- :: -webkit-scrollbar
-
为了区分伪元素和伪类,建议伪元素使用2个冒号,比如::first-line
-
伪元素用于选择某一个具体的元素中某一个或某些具体的部分
-
行内替换元素一般不能设置伪元素,因为对其设置伪元素其实本质
是给其占位元素进行设置,最终会被实际需要渲染的元素给替换掉
::first-line
,::first-letter
::first-line
可以针对首行文本设置属性
::first-letter
可以针对首字母设置属性
/* .lorem的第一行文本的字体颜色设置为红色 */
.lorem::first-line {
color: red;
}
/* .lorem的第一行文本中第一个字的字体颜色设置为红色 */
.lorem::first-letter {
color: red;
}
::before
,::after
::before
和::after
用来在一个元素的内容之前或之后插入其他内容(可以是文字、图片)
::before
和::after
常通过 content 属性来为一个元素添加修饰性的内容
往一段文本的前后加入对应的内容的时候,我们可以在元素的前后插入对应的内容
<div>
<span>before</span>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
<span>after</span>
</div>
这样做存在如下问题:
- 如果多处文本前后需要添加相同的内容的时候,这么做必须需要重复编写大量相同的代码
- 因为文本内容和span元素之间有换行,所以在前后插入的元素和文本之间必然存在一个空格
此时,CSS就为我们提供了::before
和::after
伪元素来实现在一个元素的前边和后边插入对应的图片或文本
基本使用
- 插入文本
/* 在.lorem后边添加上foo文本 */
.lorem::after {
/* 设置的内容 */
content: 'foo';
/* 对插入的内容设置对应的样式 */
color: red;
font-size: 30px;
}
- 插入图片
/* 在.lorem后边插入图片 */
.lorem::after {
/*
1. 可以使用url函数来设置插入的图片的路径
2. url函数的参数可以使用引号进行包裹
3. 在css中的引号 推荐使用 双引号 而不是 单引号
*/
content: url("./images/avatar.jpg");
color: red;
font-size: 30px;
}
- 插入自定义图形
/* 在.lorem后边插入一个 50 * 50的红色矩形 */
.lorem::after {
/*
对于伪类元素 content属性是不可以省略的
即使不需要设置插入的内容 --- 此时可以使用空字符串进行代替
*/
content: "";
/*
默认情况下,::before 和 ::after 插入的元素
都是行内非替换元素 所以需要将他们转换为行内块元素
因为 行内级元素 是无法设置对应的width和height的
*/
display: inline-block;
background-color: red;
width: 50px;
height: 50px;
}
:: -webkit-scrollbar
可以通过::-webkit-scrollbar
来控制滚动条的样式,一般用于清除默认的滚动条
.lyrics::-webkit-scrollbar {
display: none;
}