CSS选择器层叠、优先级、冲突、继承、以及属性值计算过程
1. 选择器分类
1.1 常规选择器
- 通配符选择器
- 元素选择器、伪元素选择器
- 类选择器、伪类选择器
- 属性选择器
- ID选择器
*{
/* 通配符选择器 */
margin: 0;
}
h1{
/* 元素选择器 */
font-weight: normal;
}
#content{
/* ID选择器 */
background-color: wheat;
}
.item{
/* 类选择器 */
padding: 10px;
}
[href]{
/* 属性选择器 */
color: red;
}
a:hover{
/* 伪类选择器 */
color: blue;
text-decoration: none;
}
span::before{
/* 伪元素选择器 */
content: '《';
}
span::after{
/* 伪元素选择器 */
content: '》';
}
复制代码
<h1>一级标题</h1>
<div id="content">
内容区块
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<a href="#">点击</a>
<br>
<span>CSS</span>
</div>
复制代码
1.2 组合选择器
- 并且选择器
- 子选择器
- 后代选择器
- 相邻兄弟选择器
- 兄弟选择器
- 分组选择器(语法糖)
div.red{
/* 并且选择器 */
background-color: red;
}
div > ul{
/* 子选择器 */
padding-left: 0;
}
div li{
/* 后代选择器 */
padding-bottom: 10px;
}
.two + li{
/* 相邻兄弟选择器 */
font-size: 1.5em;
}
.six ~ li{
/* 兄弟选择器 */
font-size: 0.6em;
}
div.red, li.two, li.six{
/* 三个并且选择器组成的分组选择器 */
color: blue;
}
复制代码
<div class="red">红色区域</div>
<div>
<ul>
<li>编号1</li>
<li class="two">编号2</li>
<li>编号3</li>
<li>编号4</li>
<li>编号5</li>
<li class="six">编号6</li>
<li>编号7</li>
<li>编号8</li>
<li>编号9</li>
</ul>
</div>
复制代码
2. 优先级
选择器 | 每一个的权重 |
---|---|
元素选择器/伪元素选择器 | 1 |
类选择器/伪类选择器/属性选择器 | 10 |
ID选择器 | 100 |
对于通配符选择器、行内样式、!important在开发中不推荐使用的这里就不做探讨了,另外下面的选择器的顺序也是按照由大到小书写的,防止造成是否是因为后面样式覆盖前面样式才产生当前结果的误解。大家可以通过先全部注释css样式,然后在逐步由下往上一个个打开查看效果,看是否因为权重才影响页面字体大小的变化。
#content span:hover{
/* 权重:111 */
font-size: 29px;
}
#content span{
/* 权重:101 */
font-size: 26px;
}
div p span:hover{
/* 权重:13 */
font-size: 23px;
}
p[class=p1] span{
/* 权重:12 */
font-size: 21px;
}
span.sp1{
/* 权重:11 */
font-size: 19px;
}
.sp1{
/* 权重:10 */
font-size: 16px;
}
span{
/* 权重:1 */
font-size: 13px;
}
p span::before{
/* 权重:3 */
content: '》';
}
span::before{
/* 权重:2 */
content: '> ';
}
复制代码
<div id="content">
<p class="p1">
<span class="sp1">CSS</span>
</p>
</div>
复制代码
3. 属性值计算过程
元素是怎么呈现的?每个元素相应的几百个CSS属性都必须有值,才能被渲染到页面上,没错,每个元素都有几百个CSS属性值,之所以我们平常只设置很少的一部分,是因为我们只关心我们需要改变的样式,那些您没有设置的样式当然就由浏览器默认样式代劳了。
关于如何查看每个元素的几百个CSS属性值,您可以通过控制台的Elements的Computed,然后选中show all就可以看到了。
所以一个元素要显示出来必须要经过下面介绍的四个步骤,在这四个步骤中最终把所有几百个CSS属性值确定了,元素才能呈现出来。让我们结合下面的事例,围绕着h1属性值的计算过程来详细解释h1元素的几百个属性值是怎么由诞生到最后确定的:
div{
text-align: center;
height: 100px;
background-color: pink;
}
h1{
color: maroon;
font-weight: normal;
font-style: italic;
}
div .red{
color: red;
}
h1.blue{
color: blue;
}
复制代码
<div>
<h1 class="red blue">属性值计算过程</h1>
</div>
复制代码
3.1. 无冲突属性值首先确定
在这一步我们首先要明确样式的两个主要来源:开发者书写的样式和浏览器默认样式 (用户设置浏览器样式这里不考虑)
- 浏览器有默认的样式:
- display: block; (无冲突,属性确定)
- font-size: 2em; (无冲突,属性确定)
- font-weight: bold; (浏览器有默认的样式和开发者设置的h1样式有冲突,待确定)
- 开发者书写的样式:
- font-style: italic; (无冲突,属性确定)
3.2. 处理冲突值
这一步是最复杂的,需要分以下三种情况:
- 1、开发者书写样式与浏览器默认样式冲突,开发者书写样式胜出。
- font-weight: normal; (开发者设置的h1样式胜出,属性确定)
- 2、选择器冲突:这里就要用到前面提到的优先级知识了,判断之后确定最终的值。三个选择器同时设置了color,权重分别为:
- h1: 权重:1
- div .red: 权重:11
- h1.blue: 权重:11
h1排除,但是后面两个权重相同,color值待定
- 3、先后顺序冲突:优先级相同,临近原则,顺序在后者胜出。这里也包括(css三种书写方式:行内>头部>外部)
- color: blue; (优先级相同,根据临近原则,属性确定)
3.3. 继承
只有跟文字相关的属性才会被继承。如果当前元素的父级元素,以及祖先元素设置了跟文字相关的属性值的话就会被继承
- text-align: center; (文字相关被继承,属性确定)
- height: 100px; (非文字相关不继承)
- background-color: pink; (非文字相关不继承)
3.4. 使用浏览器默认值
其他的开发者没有设置样式的就全部使用浏览器的默认样式值
- height: 45px; (使用h1字体默认的高度值)
- background-color: transparent; (背景色使用默认值透明,在页面看到h1的背景色也是粉色,但是这不是继承,而是本身透明,才让后面的颜色显示了出来,关于这点要特别注意。)
最后,说一下层叠这个词,我觉得层叠发生在属性值计算的整个过程,从第一步首先剥离出没有冲突的属性值,紧接着,第二步解决冲突,第三步的继承,再到最后托底的浏览器的默认样式,处处都有层叠的痕迹,我想这也是CSS第一个单词Cascade对这一技术的高度概况了。
作者:零寂
链接:https://juejin.cn/post/6896414154753015815
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。