两部分问题:
具体来说,我想澄清一下JavaScript和CSS与JavaScript的不同之处或原因,你需要专门等到window.onload,这样解释器才能正确地获取getElementById。但是,在CSS中,您可以选择样式并将样式应用于类和ID,而且所有样式都非常狡猾。
(如果它甚至重要,假设我指的是一个带有外部样式表的基本HTML页面)
答案 0 :(得分:22)
CSS渲染是一个有趣的话题,所有竞争对手都在努力加速视图层(HTML和CSS)渲染,以便在眨眼间为最终用户提供最佳结果。
首先,是的,不同的浏览器都有自己的CSS解析器/渲染引擎
所有这些渲染引擎都包含CSS解释器和HTML DOM parser。
所有这些引擎都遵循以下列出的模型,这些是W3C standard
的集合注意:所有这些模型都是相互关联和相互依赖的。他们是 不是单独的模型定义标准来呈现CSS。这些模型 阐明了如何根据内联样式等优先级处理CSS, 特殊性等。
第1阶段:
所有浏览器都从服务器下载HTML和CSS脚本,首先将HTML标记解析为名为内容树的树中的DOM节点。
正在解析的HTML文档浏览器渲染引擎构建另一个名为渲染树的树。这棵树按照它们显示的顺序是视觉元素。
Firefox将其称为框架,而Webkit人员将其称为Renderer或Renderer对象。
见下图:(来源:HTML5 Rocks)
第2阶段:
完成上述过程后,这两棵树都会经过布局过程,这意味着浏览器会告诉视口每个节点必须放在屏幕上。
这被定义为W3C 的定位方案(请点击此链接获取详细信息),它指示浏览器如何以及在何处放置元素。以下是3种类型。
第3阶段:
现在最后一个阶段叫做绘画。这是一个渐进的过程,渲染引擎遍历每个渲染树节点并使用UI后端层可视地绘制它们。此时,所有visual Fx都应用为字体大小,背景颜色,表绘画等。
注意:如果您尝试打开任何一个,可以清楚地看到此阶段 慢速连接的网页。大多数现代浏览器更好用户 经验尝试尽快显示元素。这给了 用户对页面正在加载并且必须等待完成的印象。
答案 1 :(得分:8)
如果您最近在任何时候都使用了慢速连接,您会发现CSS会在(慢慢地)出现时应用于元素,实际上会在DOM结构加载时回复页面内容。由于CSS不是一种编程语言,它不依赖于在给定时间可用的对象被正确解析(JavaScript),并且浏览器能够简单地重新评估页面的结构,因为它通过以下方式检索更多的HTML将样式应用于新元素。
也许这就是为什么即使在今天,Mobile Safari的瓶颈始终不是3G连接,但它是页面渲染。
答案 2 :(得分:6)
是的,浏览器内置了一个CSS解释器。你没有“等到window.onload”的原因是因为虽然Javascript是图灵完整的命令式编程语言,但CSS只是浏览器的一组样式规则适用于它遇到的匹配元素。
答案 3 :(得分:6)
浏览器从右到左读取CSS行。这就像Google和Mozilla所说的那样。谷歌表示,引擎会从右到左评估每条规则'在http://code.google.com/speed/page-speed/docs/rendering.html。 Mozilla说'样式系统通过从键选择器开始匹配规则,然后向左移动'在https://developer.mozilla.org/en/Writing_Efficient_CSS
以CSS行为例:' .item h4'。浏览器首先搜索所有' h4'页面上的标签,然后查看h4标签是否有父类,其中包含类名' item'。如果找到一个,则应用CSS规则。
答案 4 :(得分:5)
我最近在谷歌页面速度上碰到了这篇文章:
当浏览器解析HTML时,它会构造一个内部文档树,表示要显示的所有元素。然后根据标准的CSS级联,继承和排序规则,将元素与各种样式表中指定的样式进行匹配。在Mozilla的实现中(也可能是其他元素),对于每个元素,CSS引擎都会搜索样式规则以查找匹配项。引擎从右到左评估每个规则,从最右边的选择器(称为“密钥”)开始,然后移动每个选择器直到找到匹配或丢弃规则。 (“selector”是规则应适用的文档元素。)
答案 5 :(得分:2)
这是我在浏览器处理HTML和CSS时发现的最佳描述:
渲染引擎将开始解析HTML文档并将标记转换为名为“内容树”的树中的DOM节点。它将解析外部CSS文件和样式元素中的样式数据。样式信息与HTML中的可视化指令一起用于创建另一个树 - 渲染树。
通常,渲染引擎的工作是:
CSS解析器
与HTML不同,CSS是context free grammar(具有确定性语法) 所以我们将CSS specification定义CSS词法和语法语法, 解析器应用于样式表。
词法语法(词汇)由每个标记的正则表达式定义:
comment \/\*[^*]*\*+([^/*][^*]*\*+)*\/
num [0-9]+|[0-9]*"."[0-9]+
nonascii [\200-\377]
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
name {nmchar}+
ident {nmstart}{nmchar}*
“ident”是标识符的缩写,就像类名一样。 “name”是元素id(由“#”引用)
语法语法在BNF中描述。
ruleset
: selector [ ',' S* selector ]*
'{' S* declaration [ ';' S* declaration ]* '}' S*
;
selector
: simple_selector [ combinator selector | S+ [ combinator selector ] ]
;
simple_selector
: element_name [ HASH | class | attrib | pseudo ]*
| [ HASH | class | attrib | pseudo ]+
;
class
: '.' IDENT
;
element_name
: IDENT | '*'
;
attrib
: '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
[ IDENT | STRING ] S* ] ']'
;
pseudo
: ':' [ IDENT | FUNCTION S* [IDENT S*] ')' ]
;
有关浏览器工作流程的详细说明,请查看此article。
答案 6 :(得分:1)
我相信浏览器会在找到CSS时对其进行解释,其结果是主体中的CSS(内联)优先于头部中的CSS(外部也是如此)