权重
根据不同的样式选择器,有不同的权重,而最终呈现的效果是根据选择器的权重和排列顺序确定的。
css采用覆盖式渲染,相同权重下总是会运用最新的样式【后来居上模式】
名称 | 权重 | 选择器 |
---|---|---|
内联样式 | 1000 | 无(使用style属性直接编写的属性) |
ID | 100 | #id |
类 | 10 | .classname |
标签 | 1 | p a div ... |
伪元素 | 1 | ::after ::before ::first-letter ::first-line |
通配符 | 0 | * |
属性 | 10 | [attr]... |
伪类 | 10 | :active :focus :focus-within :link :visited |
父子 | 分别计算 | parent > children |
后代 | 分别计算 | parent children |
相邻 | 分别计算 | element + element |
兄弟 | 分别计算 | element ~ element |
权重计算是加权计算,依次将各个基础选择器的权重加起来得到最终的权重
!important
在css权重中,这个属性将扮演很重要的角色。这个属性将直接提升该选择器的权重为顶级。因此,不可以随便使用
[attribute] 选择器介绍
属性选择器通配包括以下几种
名称 | 说明 |
---|---|
[attribute] | 匹配包含该属性名称的元素 |
[attribute=value] | 匹配包含该属性名称和值的元素 |
[attribute|=value] | 匹配包含该属性名称且开头为value的元素,必须是整个单词 |
[attribute~=value] | 匹配包含该属性名称且值包含value的元素 |
[attribute^=value] | 匹配属性值以指定值开头的每个元素 |
[attribute$=value] | 匹配属性值以指定值结尾的每个元素 |
[attribute*=value] | 选择包含该属性名称且包含该值的元素 |
不管是何种匹配,各种选择器的权重都是10,也就是说看起来是有匹配精准度的影响
但是本质上都属于一般属性选择器,遵循选择器权重的规则
其他选择器
名称 | 说明 | 作用 |
---|---|---|
A>B | 父子选择器 | 匹配A元素直接下一级的B元素集合 |
A B | 后代选择器 | 匹配A元素的下的所有B元素集合 |
A+B | 相邻选择器 | AB元素在相同的父元素下,匹配紧接着A元素的B元素 |
A~B | 兄弟选择器 | AB在相同父元素下,匹配A元素之后的B元素集合 |
不管是何种匹配,各种选择器的权重都是AB各自基础选择器的加权
也就是说看起来是有匹配精准度的影响,但是本质上都对符号表示没有影响,只遵循选择器权重的一般规则
匹配效率
我们需要对渲染页面的速度有所保证,那最直接相关的就是渲染效率。而影响渲染效率的就是样式的匹配效率
举个例子:div a .name 和 .name a div
在两个选择器都能匹配到相同元素的情况下,看起来右侧速度更快,但是事实上左侧速度更快。
实际上是因为,css渲染时,加载器是通过从右向左依次匹配,因此,快速缩小范围,以便更快的匹配到所需要的元素内容。
不过这个例子不算太恰当,但是事实上就是如此。
顺带一提,属性和伪类效率很低,至于为什么低,还不是很明确
优化
在保证可读性的前提下尽量使用class选择器
<div class="nav">
<span class="nav-item"></span>
<span class="nav-item"></span>
<span class="nav-item"></span>
</div>
在写样式时
.nav-item { /**/ }
而不必要的使用
span.nav-item { /**/ }
或者
.nav .nav-item { /**/ }
因为如果限定选择内容,那么就不需要继续向左寻找。
优先考虑这种以类名递进关系演进的class效率上会更高一些