# 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>

image-20220723151636520

# 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>

image-20220719131752156

如何查看元素的默认值

要了解一个属性的默认值,可以把这个属性值设置为 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>

image-20220707161721440

# 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 它是关键字 initialinherit 的组合,如果属性有继承性,则继承父元素,没有则为默认值
<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>

image-20220723153827475

# 二、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>

image-20220719141324349

# 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>

image-20220709190141069

# 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>

image-20220709133706358

# 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>

image-20220709135551251

# 三、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>

image-20220709162624874

案例 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>

image-20220723161534329

注意事项:

  • 在进行选择器权重计算时不允许进行进位
  • 例如,20 个类选择器仅仅意味着 20 个十位,而不能视为 两个百位,也就是说,无论多少个类选择器的权重叠加,都不会超过一个 ID 选择器。
  • 在比较选择器优先级时,从左往右比较,一位一位比较,如果千位不相同,以大的为主,如果千位相同,是比较下一位。下一位的比较规则与上一位一样。

# 3、!important 提升权重

TIP

  • 当在一个样式声明中使用一个 !important 规则时,此声明将覆盖任何其他声明,包括行内样式。
  • 虽然,从技术上讲,!important 与优先级无关,但它与最终的结果直接相关
<style>
  div {
    color: red !important;
  }
  #box {
    color: orange;
  }
</style>
<body>
  <div style="color: blue">文本内容</div>
</body>

image-20220709144523227

注:

  • 只要 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 伪元素选择器
image-20220708222925929
<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 背景样式
原始效果 鼠标悬停效果
image-20220709165142067 image-20220709165113529
<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>
上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X