层叠样式表 (Cascading Style Sheets,缩写为 CSS )是一种样式表语言,用来描述 HTML 或 XML(包括如 SVG、MathML 或 XHTML 之类的 XML 分支语言)文档的呈现方式。CSS 描述了在屏幕、纸质、音频等其他媒体上的元素应该如何被渲染的问题。
现在的一切都是没有版本号的 CSS,就像没有ES7、8、9这样的称呼。
CSS 的使用方式主要有三种:
-
内联样式:直接在 HTML 元素中使用
style
属性定义样式。例如:html<p style="color: red;">This is a red paragraph.</p>
-
内部样式表:在 HTML 文档的
<head>
标签内定义一个<style>
标签,并在其内部编写 CSS 规则。例如:html<head> <style> p { color: blue; } </style> </head>
-
外部样式表:创建一个单独的
.css
文件,在其中编写 CSS 规则,然后在 HTML 文档的<head>
标签中使用<link>
标签链接到这个外部文件。例如:html<head> <link rel="stylesheet" href="styles.css"> </head>
当三种方式同时出现的时候,内联样式 > 内部样式 = 外部样式(后来者居上)
如果同一个样式表的情况下,通过不同的选择器选中同一个元素,样式是如何呈现的呢?
简单来说,一个特殊规则和四个基础选择器的权重: !important
> ID选择器 > 类元素选择器 > 元素选择器 > 通配符选择器
一个选择器的优先级可以说是由三个不同的值(或分量)相加,可以认为是百(ID)十(类)个(元素)------三位数的三个位数:
- ID:选择器中包含 ID 选择器则百位得一分。(1,0,0)
- 类:选择器中包含类选择器、属性选择器或者伪类则十位得一分。(0,1,0)
- 元素:选择器中包含元素、伪元素选择器则个位得一分。(0,0,1)
备注: 通用选择器(*
)、组合符(+
、>
、~
、' ')和调整优先级的选择器(:where()
)不会影响优先级。
否定(:not()
)和任意匹配(:is()
)伪类本身对优先级没有影响,但它们的参数则会带来影响。参数中,对优先级算法有贡献的参数的优先级的最大值将作为该伪类选择器的优先级。
备注: 每一个选择器类编都有它自己的优先级等级,它们不会被具有较低优先级的选择器覆盖。例如,权重为一百万 的类 选择器不会覆盖权重为一 的 ID 选择器。
评估优先级的最佳方法是对不同的优先级等级单独进行评分,并从最高的等级开始,必要时再计算低优先级等级的权重。即,仅当某一列的优先级权重相同时,你才需要评估下一列;否则,你可以直接忽略低等级的选择器,因为它们无法覆盖高优先级等级的选择器。
内联样式,即 style
属性内的样式声明,优先于所有普通的样式,无论其优先级如何(1,0,0,0)。!important
这个特殊的 CSS 可以用来覆盖所有上面所有优先级计算(1,0,0,0,0)。
上面说了这么多,下面看一段之前百度面试题?如果深究可以到浏览器渲染原理
xml
<style>
div{
color:red;
}
</style>
<div>
<a href="">a链接</a>
<p>p标签</p>
</div>
这里面有坑,很明显的页面展示p标签的字是红色的,没问题。a标签呢?紫色的... 原来,a标签如果 href 有 # 号的话,才是蓝色的;空的时候是紫色的。当然这个只是其中一点。
那p标签是如何变红的?Inherited from div
继承自div,什么时候用继承,比如文字字体样式、行高等。
- 哪些属性可以被继承?
- 文字,字体相关的属性,大多都能被继承
- 哪些属性不可以被继承?
- 宽高、背景、布局定位
说完上面两个点之后,我们还要知道浏览器渲染原理:
- 当浏览器解析HTML文档时,首先,浏览器会构建一棵表示文档结构的DOM树。接着,浏览器根据CSS规则生成另一棵树------渲染树,该树包含了文档中所有可见元素及其计算后的样式。
- 从父元素开始渲染,然后才是子元素
- 在渲染的时候,每一个元素的所有CSS属性必须有值。
- 样式声明(样式表-自定义/浏览器默认样式表
user agent stylesheet
) - 计算层叠(权重问题)
- 比较重要性。很多时候浏览器都有默认的样式,所以在开发的时候需要默认清空一些样式。清空的样式是我们自己定义的,肯定比浏览器默认的要重要。 (自己定义 > 浏览器默认)
- 比较特殊性。假如都是自己定义的,就计算权重(a,b,c)(计算选择器权重)
- 比较源次序(权重一致,后来者居上)
- 从父元素那里继承
- 赋予默认值
- 样式声明(样式表-自定义/浏览器默认样式表
- 最后浏览器按照渲染树的内容和布局信息绘制页面。
css
我们重新理一下上面的面试题:
// 打开控制台 Elements 查看 p标签 的 Styles
p { // user agent stylesheet
display: block;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
}
div { // Inherited from div
color: red;
}
p标签因为继承了div的字体颜色,所以显示红色。
// 打开控制台 Elements 查看 a标签 的 Styles
a:-webkit-any-link { // user agent stylesheet
color: -webkit-link;
cursor: pointer;
text-decoration: underline;
}
div { // Inherited from div
color: red;
}
a标签因为被浏览器设置了默认样式color: -webkit-link;所以有自己的默认颜色。
点击Computed之后看到 color:rgb(85, 26, 139),所以是紫色的。
CSS 在浏览器中的渲染原理主要包括以下几个步骤:
-
HTML 解析和 DOM 构建: 浏览器首先读取 HTML 文档,并将其转换为一个内部表示,称为 Document Object Model(DOM)。DOM 是一种树状结构,代表了文档的元素及其关系。
-
CSSOM 的构建: 当浏览器遇到外部或内联样式表时,它会解析这些 CSS 规则,并创建一个 CSS Object Model (CSSOM)。CSSOM 是样式规则的树状结构,反映了它们之间的层叠和继承关系。
-
构造渲染树: 渲染树是由 DOM 和 CSSOM 合并而成的。对于每个 DOM 节点,浏览器都会查找匹配的 CSSOM 规则,并将它们应用到该节点上。这个过程被称为"计算样式"或"样式计算"。渲染树只包含可见元素和它们的相关样式信息。
-
布局: 一旦渲染树构建完成,浏览器需要确定每个元素在页面上的确切位置。这个过程称为"布局"或"重排",即计算每个元素的几何属性,如宽度、高度和位置。
-
绘制: 现在浏览器知道每个元素的位置和大小,可以开始将它们画到屏幕上。这个过程包括填充颜色、描边边框、绘制文本等。这一步也被称为"栅格化"。
-
合成: 对于复杂的页面,可能会有多个图层。为了优化性能,浏览器会对这些图层进行分组,并将它们合并成一个单一的图像。这个过程称为"合成"。