深度学习CSS

原文:https://forum.juejin.cn/youthcamp/post/7054101680580722724?from=1

当我们试图查看 CSS 转换后的 AST 结构以这个为例

.black{
width:1rem;
height:100%;
}
这是 CSSTree 解析的 AST JSON (删除一些不必要的属性之后) 如下

{
"type": "StyleSheet",
"children": [
{
"type": "Rule",
"prelude": {
"type": "SelectorList",
"children": [
{
"type": "Selector",
"children": [
{
"type": "ClassSelector",
"name": "black"
}
]
}
]
},
"block": {
"type": "Block",
"children": [
{
"type": "Declaration",
"important": false,
"property": "width",
"value": {
"type": "Value",
"children": [
{
"type": "Dimension",
"value": "1",
"unit": "rem"
}
]
}
},
{
"type": "Declaration",
"important": false,
"property": "font-size",
"value": {
"type": "Value",
"children": [
{
"type": "Dimension",
"value": "10",
"unit": "px"
}
]
}
},
{
"type": "Declaration",
"important": false,
"property": "height",
"value": {
"type": "Value",
"children": [
{
"type": "Percentage",
"value": "100"
}
]
}
}
]
}
}
]
}
当静态的 CSS 字符串经过转换后的 AST 就可以进行计算了。从 prelude 属性中取出查询器根据其计算权重并递归进行处理为 block 属性提供上下文支持。 block 就是具体属性的内容部分了。

AST 中的关键词
SelectorList:他的 Children 属性记录了 CSS 选择器的类型及名字
property: css 的属性
value: 属性对应的值
important: 值可以为 false 或 true , !important 存在时则为 true
因此大致解析情况是在读取 DOM 树的同时解析 CSS ,从

CSS 计算过程
1.drawio (1).png

原始 DOM 树结构与样式规则

filtering:经过(对应用到该页面的规则用以下条件进行筛选:选择器匹配、属性有效、符合当前 media 等)得到声明值(Declared Values,一个元素的某属性可能有0到多个声明值。如:p{font-size:16px}和p.text{font-size:1.2em})

cascading:(按照来源、!important、选择器特异性、书写顺序等选出优先级最高的一个属性值)得到层叠值(Cascaded Value,在层叠过程中,赢得优先级比赛的那个值。如 1.2em)得到层叠值(Cascaded Value,在层叠过程中,赢得优先级比赛的那个值。如 1.2em)

defaulting:(当层叠值为空时,使用继承或初始值)得到指定值(Specified Value,经过cascading和defaulting之后,保证指定值一定不为空)

resolving:(将一些相对值或者关键字转化成绝对值。如em转为px,相对路径转为绝对路径)得到(Computed Value,一般来说是,浏览器会在不进行实际布局的情况下,所能得到的最具体的值。如60%。继承是继承的计算值)

formatting:(将计算值进一步转换。如关键字、百分比等都转为绝对值)得到使用值(Used Value,进行实际布局时使用的值,不会再有相对值或关键字。如400.2px)

constraining:(将小数像素值转为整数)得到实际值(渲染时实际生效的值。如400px)

大体流程可以称之为,从 csstree 中过滤出与当前属性值相关的一个或多个值,经过层叠权重的比较,选出最高权重的值,如果当前值为空则使用默认或初始值,如果当前值为相对值则转为绝对值,得到当前的可计算值,再使用当前计算值进行运算,最后将结果值转为整数。

CSS 书写顺序
浏览器并不是一获取到 CSS 样式就立马开始解析,而是根据 CSS 样式的书写顺序将之按照 DOM 树的结构分布渲染样式,然后开始遍历每个树结点的 CSS 样式进行解析,此时的 CSS 样式的遍历顺序完全是按照之前的书写顺序。

在解析过程中,一旦浏览器发现某个元素的定位变化影响布局,则需要倒回去重新渲染。(详细内容参考回流重绘)

参考以下代码

width: 150px;
height: 150px;
font-size: 24px;
position: absolute;
当浏览器解析到 position 的时候突然发现该元素是绝对定位元素需要脱离文档流,而之前却是按照普通元素进行解析的,所以不得不重新渲染。

渲染引擎首先解除该元素在文档中所占位置,这就导致了该元素的占位情况发生了变化,其他元素可能会受到它回流的影响而重新排列。

我们对可以代码进行调整:

position: absolute;
width: 150px;
height: 150px;
font-size: 24px;
推荐书写顺序

  1. 定位属性

position display float left top right bottom overflow clear z-index
2. 自身属性

width height padding border margin background
3. 文字样式

font-family font-size font-style font-weight font-varient color
4. 文本属性

text-align vertical-align text-wrap text-transform text-indent text-decoration letter-spacing word-spacing white-space text-overflow
5. CSS3中新增属性

当页面发生重绘时,它们会降低浏览器的渲染性能。建议最后书写

content box-shadow border-radius transform

原文:

posted @ 2022-05-01 15:36  黑蛋的博客  阅读(49)  评论(0编辑  收藏  举报