# CSS 三大特性:继承、层叠性、优先级
TIP
我们实际的开发中,经常会遇到 CSS 应用时的冲突问题。比如本来应该产生效果的样式没有生效,或有时候不想要的效果硬实现了,为什么会产生这种效果,我们搞不清原因。
接下来我们要学的 CSS 三大特性:继承性、层叠性、优先级就是为解决这些问题而来的。
但是在学习之前,我们先来看一个 CSS 样式发生冲突的案例,看下在这个案例当中会发生那些样式冲突,带着这些问题我们再来学习,效果会更好。
CSS 样式发生冲突案例:
<style>
.box {
font-style: italic;
}
/* 优先级 0012 */
.box p span {
color: blue;
}
/* 优先级 0011 */
span:hover {
color: red;
font-size: 30px;
}
</style>
<body>
<div class="box">
<p><span>我是span中内容</span></p>
</div>
</body>
思考以下 3 个问题,并给出答案:
- 鼠标滑动到 span 上时,span 中的文字有没有放大和变红?为什么?
- 如果鼠标滑动到 span 上时,想实现文字变红,如何修改代码,达到效果?
- span 标签最终的呈现效果是什么?为什么是这样的?
# 一、CSS 继承性
CSS 的继承性
是指特定的 CSS 属性会向下传递到子孙元素。即祖先元素设置,后代元素即生效
<style type="text/css">
.box {
/* 宽300px 无继承性 */
width: 700px;
/* 边框线 无继承性 */
border: 1px solid red;
/*
color、text-align、font-size都有继承性
都可以继承给到其子孙元素
*/
color: red;
text-align: center;
font-size: 14px;
}
.box p {
background-color: khaki;
/* p中自已设置了font-size,所以不会继承父元素的 */
font-size: 20px;
}
</style>
<body>
<div class="box">
<p>我的文字颜色红色和文字水平居中,都是继承于父元素box的</p>
</div>
</body>
# 1、CSS 继承性遵顺“就近原则”
TIP
- 如果元素自身没有设置某个具有可继承的属性,则会向他的父元素继承
- 如果父元素没有,则再往上继承父元素的父元素的这个属性,一层层向上找,如果找不到,就以默认的样式显示
<style>
.box {
/* width不可继承属性 */
width: 400px;
/* border不可继承属性 */
border: 1px solid #666;
/* text-align 可继承属性 */
text-align: center;
}
.box1 {
/* color 可继承属性 */
color: blue;
}
</style>
<body>
<div class="box">
<div class="box1">
<h3>CSS继承性遵顺“就近原则”</h3>
</div>
</div>
</body>
如何查看元素的默认值
要了解一个属性的默认值,可以把这个属性值设置为 initial ,然后审查元素,在 computed 面板中可以看到其默认值,如color:initial;
# 2、可继承和不可继承属性有哪些
可继承属性
文本相关的属性普遍具有继承性,只需要给祖先标签设置,即可在后代所有标签中生效
- 字体系列: font-size、font-family、font-style、font 、font-weight
- 文本系列:color 、text-align、text-indent、line-height、word-spacing、letter-spacing、text-transform
- 列表布局属性:list-style、list-style-type、list-style-image、list-style-position 等
- 光标属性:cursor 光标显示为何种形态
- 元素可见性:visibility 控制元素显示和隐藏
不可继承属性
- 盒子模型:display、margin、border、padding、height、min-height、max-height、width、min-width、max-width
- 定位相关:position、left、right、top、bottom、z-index
- 浮动:float、clear
- 其它:background、overflow、table-layout、vertical-align、page-break-after、page-bread-before 和 unicode-bidi
# 3、a 标签的 color 值默认不继承
<style type="text/css">
/*
.box中文字为红色,
但a标签没有设置color属性,也没有继承父元素的color属性,以默认值出现
*/
.box {
color: red;
}
</style>
<body>
<div class="box">
<a href="">我是超链接</a>
</div>
</body>
# 4、line-height 的继承性
TIP
line-height 的值有三种单位,在继承时的差异点
父元素 line-height 值 | 继承规则 | 子元素 line-height 值 |
---|---|---|
50px | 直接继承该 值 | 50px |
2 | 直接继承该比例 | 2 |
200% | 继承%百分比计算后的值 如果父元素 font-size: 20px; 则计算得到父元素 line-height 的值是 40px; | 40px |
<style>
.box {
width: 350px;
height: 100px;
background-color: pink;
font-size: 30px;
/* 情况一: 子元素直接继承父元素值 */
line-height: 50px;
/*
情况二: 子元素直接继承父元素值
line-height:2;
*/
/*
情况三: 子元素继承%百分比换算后的值 200%*30=60px
line-height:200%;
*/
}
.item1 {
font-size: 20px;
/* 情况一: 从父元素直接继承过来 line-height:50px; */
/* 情况二:从父元素直接继承过来 line-height:2; 最终2*20px 子元素行高为40px */
/* 情况三:子元素继承父元素%百分比换算后的值60px ,所以子元素line-height:60px */
}
</style>
<body>
<div class="box">
<div class="item1">直接继承父元素的line-height:50px;</div>
</div>
</body>
# 5、body 标签样式初始化
TIP
因为文字相关属性有继承性,所以通常会设置 <body>
标签的字号、颜色、行高等,这样就能当做整个网页的默认样式了。
/* 以下代码来自京东 你可能会有疑问,字体类型为什么没有引号引起来 */
body {
font: 12px/1.5 Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\5B8B\4F53",
sans-serif;
color: #666;
}
# 6、设置继承性
TIP
默认不继承的属性想要继承,可以把属性值设为inherit
。表示这个属性的值继承父元素的。
扩展补充知识:
css 属性通常会有以下三个值:
initial
设置属性值和浏览器默认样式相同inherit
属性值默认继承父元素unset
它是关键字initial
和inherit
的组合,如果属性有继承性,则继承父元素,没有则为默认值
<style type="text/css">
.box {
width: 100px;
height: 100px;
/* 2px 实线 红色 边框 */
border: 2px solid red;
}
.item {
width: 50px;
height: 50px;
/* 边框是没有继承性的,所以要让他继承父元素的边框样式,就把值设为inherit */
border: inherit;
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
# 二、CSS 层叠性
TIP
- 层叠是 CSS 的一个基本特征,它是一个定义了如何合并来自多个源(css 规则)的属性值的算法。
- 它在 CSS 处于核心地位,CSS 的全称层叠样式表正是强调了这一点。
我们来看下面这个例子
有两个 css 规则同时作用于同一个 div 标签,那最后之两个 css 规则中的属性值是如何合并计算的,以谁为主呢?这就需要一套明确的规则来规定,这套规则就是指CSS 层叠性。
<style>
/* css规则1 */
.box {
color: red;
font-size: 30px;
}
/* css规则2 */
div {
color: blue;
}
</style>
<body>
<div class="box">艾编程</div>
</body>
# 1、CSS 层叠性解读
TIP
- 所谓的层叠性是指多个 CSS 规则可以同时作用于同一个标签,效果 叠加,并不完全 覆盖。
- css 的层叠性有两层含义:叠加 和 覆盖
- 不同选择器作用同一元素,不同属性会叠加,相同属性会 覆盖 。
- 在 覆盖 时需要遵顺以下两大原则:"就近原则" 和 "优先级"
# 2、CSS 的叠加原理
不同选择器作用于同一元素,不同属性会叠加作用于元素。
<style>
/*
以下三个选择器中的样式属性都不一样,则会叠加
最后div效果:
背景颜色:黄色
字体大小:20像素
字体颜色:红色
*/
div {
background: yellow;
}
div {
font-size: 20px;
}
.box {
color: red;
}
</style>
<body>
<div class="box">文本内容</div>
</body>
# 3、CSS 的覆盖原则
就近原则
- 当两个或多个 优先级相同 的选择器作用到同一个元素时。如果出现相同的属性,则以写在后面的选择器中的属性为主。
- 所谓的就近原则是指,离 html 元素最近的那个为主。本质和选择器谁写在后面以谁为主是一个意思。
/*
以下两个选择器的优先级一一样,
则相同属性会覆盖,覆盖时,以写在后面的为主
不同属性会叠加。
*/
div {
/* background属性会叠加 */
background: yellow;
/* 无效 */
color: blue;
}
div {
/* font-size属性会叠加 */
font-size: 20px;
/* 选择器优先级一样,以后面为主,则此属性生效 */
color: red;
}
/* 最终的CSS实际效果 */
/*
div{
background:yellow;
font-size:20px;
color:red;
}
*/
优先级
- 当两条或多条规则(选择器)作用到同一个元素,如果出现相同的属性,则以优先级高的为主。
<style>
/*
基础选择器优先级从高到低分别是: id选择器 >class选择器 >标签选择器
id优先级最高,则最后以id中的color:red为最终显示效果
*/
#box {
/* 生效 */
color: red;
}
.box {
/* 不生效 */
color: blue;
}
div {
/* 不生效 */
color: green;
}
</style>
<body>
<div class="box" id="box">div中内容</div>
</body>
# 4、层叠性的冲突处理
TIP
- 不同 css 规则集同时作用于同一个标签,不同属性相互叠加,相同属性会覆盖。
- 相同属性覆盖,首先需要计算选择器的权重,最后以选择器权重高的为主。
- 如果选择器权重相同,则写在后面的会覆盖写在前面的。
- 如果想要实现的效果,因为选择器因为权重低而不生效,则通过提高选择器权重来达到效果。
<style>
/* id权重最高,样式全部应用 */
#box {
width: 200px;
}
/*
.box与.box2权重一样,相同属性叠加,不同属性,以写在后面的为主
最后生效样式:
color:orange; background:skyblue; font-size:30px
*/
.box {
color: blue;
background-color: skyblue;
}
.box2 {
color: orange;
}
/*
div权重低于.box和.box2,相同属性叠加,不同属性,以权重高的为主
则color不生效,border属性生效
*/
div {
color: green;
font-size: 30px;
}
/*
计算后最终生效样式
width:200px;
color:orange;
background-color:skyblue;
font-size:30px;
*/
</style>
<body>
<div class="box2 box" id="box">文本内容</div>
</body>
# 三、CSS 选择器优先级
TIP
- 当多个 css 规则集同时作用于同一个 HTML 标签时,不同属性会叠加,但相同属性会发生覆盖。
- 在发生覆盖时,浏览器通过 选择器的优先级 来判断以那个选择器中的属性值为主,从而在该元素上应用这些属性值。
# 1、单个选择器类型的权重
TIP
- 我们前面讲过基础选择器类型的优先级,从高到低为:id 选择器>class 选择器>标签选择器>通配符选择器。
- 但我们学过的选择器类型远不止上面这 4 种,那这些选择器都放在一起,谁的优先级会更高一些呢?
- 本质上,不同类型的选择器有不同的分数值,分数值越高,选择器的权重越高,具体如下表。
选择器的类型 | 实例 | 选择器权重 | 等级 |
---|---|---|---|
!important | div{ color:red!important; } | 无穷大 | 特级 |
行内样式(style 属性中样式) | style='color:red;' | 1000 | 第一等级 |
id 选择器 | #id | 0100 | 第二等级 |
class、伪类、属性选择器 | .box、:hover、[type='text'] | 0010 | 第三等级 |
标签选择器、伪元素选择器 | div、::after、::before | 0001 | 第四等级 |
通配符、子选择器、相邻选择器等 | *、> 、+、~ | 0000 | |
继承的样式 | 0000 |
提示:
* 通配符 权重实际是要大于继承的样式的
# 2、复杂选择器优先级计算
TIP
- 优先级就是分配给指定的 CSS 声明的一个权重
- 选择器的优先级是由选择器中的每一种 选择器类型的数值(权值) 相加的最终结果来决定。
- 一个选择器的优先级是由四个部分相加计算得来的(数值越大,代表选择器的优选级越高)。
以下是复杂选择器的权重计算规则
- 这里要对照我们前面讲过的单个选择器类型的选择器权重来看
- 这里的行内样式
<p style="color: red"></p>
并不是选择器,但我们把他放在一起,是因为了他会影响我们最终的结果
选择器 | 千位 | 百位 | 十位 | 个位 | 优先级 |
---|---|---|---|---|---|
行内样式 如: <p style="color:red"></p> | 1 | 0 | 0 | 0 | 1000 |
div p | 0 | 0 | 0 | 2 | 0002 |
#box div p | 0 | 1 | 0 | 2 | 0102 |
.box .item h3 | 0 | 0 | 2 | 1 | 0021 |
.box:hover p | 0 | 0 | 2 | 1 | 0021 |
案例 1:
鼠标放在 p 标签上,文字会变成红色吗 ?
<style>
/* 优先级 0011 */
p:hover {
color: red;
}
/* 优先级 0011 */
.box p {
color: blue;
}
/*
两选择器优选级相同,都是0011 ,则以写在后面的为主,相同属性发生覆盖。
则最终效果为 blue蓝色,鼠标滑上去文字并不会变色
*/
</style>
<body>
<div class="box">
<p>文本内容</p>
</div>
</body>
答:
鼠标滑动到 p 上面,文字并不会变成红色
案例 2:
以下案例中的 p 标签的最终显示效果怎样的?
<style>
/* 优先级:100 */
#title {
color: red; /*生效*/
}
/* 优先级:20 */
.box .title {
/* 不生效,以#title为主 */
color: blue;
}
/* 优先级:10 */
.title {
/* 生效 */
font-size: 16px;
}
/* 优先级:2 */
div p {
/* 不生效,以.title中为主 */
font-size: 40px;
}
</style>
<body>
<div class="box">
<p id="title" class="title">p中内容</p>
</div>
</body>
案例 3:
以下案例中,p 标签中的文字最终是以什么颜色显示?
<style>
/* 单个选择器类型优先级从高到低:id > class > 标签 */
/* 优先级 0201 */
#box1 #box2 p {
color: red;
}
/* 优先级 0212 三个中优先级最高,则以他为主 */
#box1 div.box2 #box3 p {
color: green;
}
/* 优先级 0031 */
.box1 .box2 .box3 p {
color: blue;
}
</style>
<body>
<div class="box1" id="box1">
<div class="box2" id="box2">
<div class="box3" id="box3">
<p>我是一个段落标签</p>
</div>
</div>
</div>
</body>
注意事项:
- 在进行选择器权重计算时不允许进行进位
- 例如,20 个类选择器仅仅意味着 20 个十位,而不能视为 两个百位,也就是说,无论多少个类选择器的权重叠加,都不会超过一个 ID 选择器。
- 在比较选择器优先级时,从左往右比较,一位一位比较,如果千位不相同,以大的为主,如果千位相同,是比较下一位。下一位的比较规则与上一位一样。
# 3、!important 提升权重
TIP
- 当在一个样式声明中使用一个
!important
规则时,此声明将覆盖任何其他声明,包括行内样式。 - 虽然,从技术上讲,
!important
与优先级无关,但它与最终的结果直接相关
<style>
div {
color: red !important;
}
#box {
color: orange;
}
</style>
<body>
<div style="color: blue">文本内容</div>
</body>
注:
- 只要 css 声明属性值后面带!important,就一定以他为主。
慎用 !important
- 不过我们要慎用!important,因为这会带来样式的冲突。后面某个地方,需要重写这个样式时,会发现根本无效。一般你在利用第三方组件或 css 框架时,如果不能重写样式,那将会失去很多色彩。
- 在某些情况下是一定要用的,比如在之前学的自定义字体时,font-family 属性后面加了!important 关键字。
# 4、总结:CSS 选择器优先级
TIP
首先要找到,有哪些选择器在控制标签元素的样式,然后按以下 5 步来分析,最终生效的 css 声明。
- 第一步:找有没有带 important 关键词的 CSS 声明,有就一定以他为主,没有看第二步
- 第二步:找有没有行内样式,有则以行内样式为主,没有看第三步
- 第三步:看选择器的优先级,优先级高的为主,如果优先级相同,则看第四步
- 第四步:优先级相同,以写在后面的为主。如果没有选择器作用于当前标签,则看第五步
- 第五步:看此 CSS 属性是否具有继承性,如果有,则继承父元素的样式,如果没有,则以默认样式显示。
# 四、测试题
# 1、看代码,回答以下三个问题
TIP
- 鼠标滑动到 span 上时,span 中的文字有没有放大和变红?为什么?
- 如果鼠标滑动到 span 上时,想实现文字变红,如何修改代码,达到效果?
- span 标签最终的呈现效果是什么?为什么是这样的?
<style>
.box {
font-style: italic;
}
.box p span {
color: blue;
}
span:hover {
color: red;
font-size: 30px;
}
</style>
<body>
<div class="box">
<p><span>我是span中内容</span></p>
</div>
</body>
TIP
1、鼠标滑动到 span 上时,span 中的文字有没有放大和变红?为什么?
- 答:不会变红,因为
span: hover;
的优先级低于.box p span
,所以最终color: blue;
2、如果鼠标滑动到 span 上时,想实现文字变红,如何修改代码,达到效果?
- 答: 把
span:hover
选择器,改成p span:hover { }
提高选择器的优先级
3、span 标签最终的呈现效果是什么?为什么是这样的?
- 答:span 最终以 16px、 蓝色 、斜体 来呈现,当鼠标滑上去时,文字会变大到 30px
解读
所以 span 中文字最终以 16px 蓝色 斜体 来呈现
.box p span
中没有font-style
属性,所以其默认的font-style
属性是继承其祖先元素 div 的font-style:italic;
.box p span
中没有定义font-size
则会继承 body 的font-size:16px
.box p span
中定义了color:blue;
当鼠标滑上去时,文字会变大到 30px
span:hover
中的 color 属性并不会生效,因为span:hover
的优先级低于.box p span
span:hover
中的font-size:30px
是生效的,因为在.box p span
中并没有声明 font-size 属性。- 鼠标滑动到
span
上时,文字只会变成 30px,并不会改变颜色
# 2、以下 span 中文字的颜色是?
<style>
.col {
color: red;
}
div p span {
color: blue;
}
</style>
<body>
<div>
<p><span>span标签的文字颜色</span></p>
</div>
</body>
答:
.col
并没有作用于 span 标签,所以控制 span 标签的字体颜色为color:blue;
蓝色
# 3、鼠标滑动到 a 标签,a 标签中文字能不能变成黄色
<style>
/* 12 */
li a:hover {
color: yellow;
}
/* 12 */
.list li a {
color: orange;
}
</style>
<body>
<ul class="list">
<li><a href="">艾编程</a></li>
</ul>
</body>
答:
li a:hover
与.list li a
的优先级一样,优先级一样,以写在后面的为主,则鼠标滑上去,文字不会变成黄色
# 4、以下 li 中和 a 中的文字颜色分别?
<style>
/* 2 */
ul li {
color: red;
}
/* 2 */
ul > li {
color: orange;
}
</style>
<body>
<ul class="list">
<li>点击进入<a href="">艾编程</a></li>
</ul>
</body>
答:
ul li 和 ul > li 的优先级是一样的,优先级一样,以写在后面的为主,则 li 最终的效果为橘黄色
# 五、案例
# 1、CSS 开关按扭
核心知识:
::checked
选择器<label>
标签应用- 后续兄弟选择器
::after
伪元素选择器
<style>
.button {
width: 60px;
height: 26px;
padding: 2px;
background-color: #ddd;
border-radius: 20px;
}
.button::after {
display: inline-block;
content: "";
width: 26px;
height: 26px;
background-color: #fff;
border-radius: 100%;
}
input {
display: none;
}
input:checked ~ .button {
background-color: skyblue;
}
input:checked ~ .button::after {
float: right;
}
</style>
<body>
<label for="on-off">
<input type="checkbox" id="on-off" />
<div class="button"></div>
</label>
<br />
<label for="on-off2">
<input type="checkbox" id="on-off2" />
<div class="button"></div>
</label>
</body>
# 2、鼠标滑动按扭效果
核心知识:
:hover
伪类选择器- 元素类型转换
- background 背景样式
原始效果 | 鼠标悬停效果 |
---|---|
<style>
.down {
display: inline-block;
width: 130px;
height: 40px;
/* 首行缩进 或用内边距+计算 或 内边距+怪异盒子模型 */
text-indent: 45px;
line-height: 40px;
text-decoration: none;
color: #d81e06;
border-radius: 10px;
background: #ddd url(images/down1.png) no-repeat 5px center;
}
.down:hover {
/* 样式重写 图片位置 重复度用.down选择器中的样式 */
background-color: #d81e06;
background-image: url(images/down2.png);
color: #fff;
}
</style>
<body>
<a href="#" class="down"> 点击下载</a>
</body>
大厂最新技术学习分享群
微信扫一扫进群,获取资料
X