作为前端,我们每天都在与CSS打交道,那么CSS的原理是什么呢?开篇,我们还是不厌其烦的回顾一下浏览器的渲染过程,学会使用永远都是最基本的标准,但是懂得原理,你才能触类旁通,超越自我。
作为前端,我们每天都在与CSS打交道,那么CSS的原理是什么呢?
一、浏览器渲染
本文的重点也就集中在第二条分支上,我们来探究一下 CSS 解析原理。
二、Webkit CSS 解析器
Webkit 使用 Flex 和 Bison 解析生成器从 CSS 语法文件中自动生成解析器。
CSSRule* CSSParser::createStyleRule(CSSSelector* selector)
{
CSSStyleRule* rule = 0;
if (selector) {
rule = new CSSStyleRule(styleElement);
m_parsedStyleObjects.append(rule);
rule->setSelector(sinkFloatingSelector(selector));
rule->setDeclaration(new CSSMutableStyleDeclaration(rule, parsedProperties, numParsedProperties));
}
clearProperties();
return rule;
}
但是我们解析所要的结果是什么?
三、CSS 选择器解析顺序
<div>
<div class="jartto">
<p>span> 111 span><p>
<p>span> 222 span><p>
<p><span> 333 <span><p>
<p><span class='yellow'> 444 <span><p>
<div>
<div>
div > div.jartto p span.yellow{
color:yellow;
}
这样的搜索过程对于一个只是匹配很少节点的选择器来说,效率是极低的,因为我们花费了大量的时间在回溯匹配不符合规则的节点。
结果显而易见了,众所周知,在 DOM 树中一个元素可能有若干子元素,如果每一个都去判断一下显然性能太差。而一个子元素只有一个父元素,所以找起来非常方便。
浏览器 CSS 匹配核心算法的规则是以从右向左方式匹配节点的。这样做是为了减少无效匹配次数,从而匹配快、性能更优。
四、CSS 语法解析过程
五、内联样式如何解析?
p > a {
color : red;
background-color:black;
}
a {
color : yellow
}
div {
margin : 1px;
}
selector
|
selector
|
weight
|
---|
a
|
color:yellow
|
1
|
p > a
|
color:red
|
2
|
p > a
|
background-color:black
|
2
|
div
|
margin:1px
|
3
|
到这里就不难理解了,对浏览器来说,內联样式与其他的加载样式方式唯一的区别就是权重不同。
六、何谓 computedStyle ?
七、眼见为实
八、有何收获?
Bad
p#id1 {color:red;}
Good
#id1 {color:red;}
当然,你非要这么写也没有什么问题,但这会增加 CSS 编译与解析时间,实在是不值当。
Bad
div > div > div > p {color:red;}
Good
p-class{color:red;}
Bad
p[id="id1"]{color:red;}
p[]{color:red;}
Good
#id1{color:red;}
.class1{color:red;}
九、总结
“学会使用”永远都是最基本的标准,但是懂得原理,你才能触类旁通,超越自我。