页面样式渲染
渲染树(Render Tree)
对于一个网页(包括小程序的Page): HTML解析成一个DOM (Document Object Model)树,样式表会解析成一个 CSSOM(CSS Object Model)树, 二者结合形成一颗渲染树。
渲染树上的样式即为最终用来渲染呈现的样式(Chrome Computed style)。
渲染节点属性选择
- 自定义样式
- 代码定义
- 客户端设置(浏览器默认样式)
- 继承(父级样式)
- CSS标准
对于渲染树上任意一个节点属性的计算:
- 如果这个节点的属性已经在样式表中定义了,优先采用定义的样式(包括代码中定义和浏览器的默认样式),对于多个定义的优先级会在后面详细解释;
- 如果没有定义,该属性默认可以继承,则向上递归查找祖先定义的该属性;
- 如果未定义,默认不能继承则采用标准的属性值(一般都会有默认属性,不会到这一步)
示例 CSS 样式选择.
样式选择优先级
1样式声明的权重
- 内联样式
- 样式选择器样式 (包括默认浏览器默认样式)
#ID
选择器.Class
选择器,属性选择器,伪类选择器Tag
标签选择器,伪元素选择器
- 内联样式之间作用与节点,具有最高的权重,包括
style=""
和JS动态修改element的样式。 - CSS定义中的ID选择器(如
#id{}
)的权重次之;在CSS定义中具有最高的权重; - CSS中类选择器(
.class{}
)和属性选择器([attribute]{}
)以及伪类选择器(:hover
)等具有相同的权重; - 标签选择器(
h1{}
)和伪元素选择器(::before
)具有相同的权重
通配选择符(universal selector)(
*
), 关系选择符(combinators) (+
,>
,~
,)和 否定伪类(negation pseudo-class)(
:not()
) 无权重。
总结,根据下面关系,应用权重最高的定义。
inline
>#id
>.class
=[attribute]
=:pseudo-class
>tag
=::pseudo-element
>*
See the Pen 定义优先级.
如果选择器级联操作,计算级联权重
2级联样式权重
前面提到,CSS定义中有3类权重id选择器,class选择器,和标签选择器。
分别统计在一个属性中,三中类型出现的频次, 选ID频次最高的,如果有多个相同则再选class权重最高的依次类推。
例如
/*1*/
#i > .content {
color:red;
}
/*2*/
.c > #i2 {
color:green;
}
/*3*/
.c > .c2.c3{
color:yellow;
}
/*4*/
#ii #ii2{
color:blue;
}
其中1和2的权重一样(一ID一class),4的权重最高(俩个ID)
如果最高权重的仍有,多个根据出现属性确定优先级。
示例 CSS 级联权重.
3定义顺序
- inline
- media query
- 代码定义或者浏览器默认,以最后出现优先
4!important
!important
声明高于所有非!important
的属性,具有最高的优先级,
多个!important
属性时通过上述再进行权重比较。
总结
完整优先级判断
属性计算的优先流程(非实际计算过程)
实践原则
- 避免使用
#id
选择器- 避免在CSS中使用
- 仅在JS操作相关内容中使用
- 慎用
!important
- 共用组件和库中应该避免使用
!important
- 能不用
!important
的则不用!important
- 使用
!important
:- 无法正常维护的代码项目中
- 只能在外层插入样式,不能修改既有任何代码的情况
- 功能单一的工具性CSS样式(如控制文本居中
.text-center{text-align:center!important}
);
- 共用组件和库中应该避免使用
- 善用
[attribute]
和:pseudo-class
- 尽量利用attribute控制样式(语义一致性)如:
button[disabled]
,.link:hover
- 尽量利用attribute控制样式(语义一致性)如:
inline
一版是JS动态修改样式使用。