CSS:级联和继承

340 阅读5分钟

最近看了一本书《深入解析CSS》,本来我对CSS是没有系统的认识的,看了这本书想写点东西总结一下, 这篇文章先写第一部分:级联和继承

CSS样式优先级分为两大类,级联和继承

级联:

CSS级联规则决定了样式冲突时胜出的样式,这三条规则按照优先级从高到低分别为:

  1. 样式表来源
  2. 选择器优先级
  3. 代码顺序

样式表来源优先级最高,如果来源一致,那么取决于选择器优先级(行内样式归纳到选择器这一条),如果选择器也一致,那么优先级取决于代码的顺序 image.png

样式表来源:

样式来源主要是就两点,一个是作者样式表(也就是咱们自己写的样式),在一个就是用户代理样式表(也就是俗称的浏览器默认样式), 比如列表有左侧内边距,有左侧小黑点(如图),链接是蓝色而且有下划线

作者样式表的优先级高于用户代理样式表

image.png

选择器优先级:

分为两部分,HTML行内样式选择器的样式

行内元素的优先级高于所有其他样式的优先级(除了!important,加了!important的样式优先级最高,另外,没有别的样式能覆盖行内样式+!important)

选择器的优先级就比较复杂了,以往背八股文的时候总是需要死记硬背,但是其实这个规则也很好理解:

  1. ID选择器最多的样式优先级最高(因为ID选择器是最为明确的选择器,所以最多的ID选择器明确程度最高)
  2. 如果ID选择器数量一致,那么类选择器最多的样式优先级最高(类选择器的明确程度仅次于ID选择器)
  3. 如果ID选择器和类选择器的数量都一样,那么标签选择器最多的样式胜出(tag选择器明确程度最低) PS:伪类选择器(:hover)和属性选择器([type="input"]与类选择器优先级相同

pps:优先级标记: 也是常常被提及的比较方法:

  • 一个行内元素为1000
  • 一个ID选择器为0100
  • 一个类选择器0010
  • 一个标签选择器为0001
  • 通用选择器的优先级是0000 比如.page-header .title这个样式的的优先级为0020,#page-title的优先级为0100,因为0100>0020,所以后者的优先级更高,这样和上面的规则是一致的ID选择器最多的样式优先级最高,前者ID选择器为0个,后者1个。
源码顺序:

这个很好理解啦,如果前边所述的优先级都相同,那么出现在代码顺序后边的样式会覆盖代码顺序在前边的样式:

.nav a {
    background-color: red;   
}

a.featured {
    background-color: orange;
}

上面两个样式的优先级相同,一个选中了.nav的后代a,一个选中了a中的.feature,因为后者出现在代码后边,所以优先级更高,会覆盖前面的样式

继承:

除了级联之外,还有一种给元素添加样式的方式:继承。

继承的样式没有优先级

image.png

但不是所有的属性都能被继承。默认情况下,只有特定的一些属性能被继承,通常是我们希望被继承的那些。它们主要是跟文本相关的属性:

color、font、font-family、font-size、 font-weight、font-variant、font-style、line-height、letter-spacing、text-align、 text-indent、text-transform、white-space 以及 word-spacing。

还有一些其他的属性也可以被继承,比如列表属性:

list-style、list-style-type、 list-style-position 以及 list-style-image。表格的边框属性 border-collapse 和border-spacing 也能被继承

可以在适当的场景使用继承。比如给 body 元素应用字体,让后代元素继承该字体,因为继承的样式没有优先级,所以很容易被覆盖

inherit关键字:

inherit关键字可以让元素继承父元素的属性,可以用来覆盖原来的值,比如:

/* 全局尚未访问链接的颜色 */
a:link{
  color:blue
}

/* 父元素 */
.footer {
  color: #666
}
/* 优先级与a:link相同,都是一个标签选择器和一个(伪)类选择器,所以全局color被父元素的#666覆盖 */
.footer a {
  color: inherit
}

<div class="footer">
    <a href="#"></a>
 </div>

a的color设置了继承,所以第三个规则覆盖了全局规则。

另外,还可以使用inherit继承一些默认不会被继承的属性,比如:

:root {
  box-sizing: border-box;
}

*,
::before,
::after {
  box-sizing: inherit;
}

如代码所示,将根元素盒模型设置为border-box,然后全局继承根元素。这么做是考虑到有的组件是使用的content-box,但是我们全局的选择器把所有元素的盒模型都改成了border-box。

所以这时候只需要把这个组件顶级容器的盒模型改成content-box,那么组件内的元素就会继承这个顶级元素,恢复到content-box:

.some-component {
  box-sizing: content-box;
}

参考:

1.深入解析CSS

2.张鑫旭大神的视频: www.bilibili.com/video/BV1TL…