一个列表

菜单
插图的大括号到像素的文章

插图的Dougal麦克弗森

括号,像素

CSS看起来不像魔法吗?好吧,在“URL互动我们来看看你的浏览器从大括号到像素的整个过程。作为奖励,我们还将快速介绍最终用户交互如何影响这个过程。我们有很多地方要讲,所以喝一杯 ,我们开始吧。

解析

继续下面的条

类似于我们在"DOM标记,“一旦CSS被浏览器下载,将CSS解析器旋转起来以处理它遇到的任何CSS。可以是单个文档中的CSS,里面的

显示HTML主体的图表,一个CSS盒,以及宽度属性,其值为50像素
浏览器从 身体元素。我们生产它的主盒,宽度为50px,的默认高度 汽车
显示树的关系图,树的主体有一个CSS框,段落有一个CSS框
现在浏览器移动到段落并生成它的主框,由于段落默认有空白,这会影响身体的高度,正如在视觉上所反映的。
显示树的图,树的主体有一个CSS框,段落有一个CSS框,现在在末尾添加了一个行框
现在浏览器移动到“Hello world”的文本,这是DOM中的一个文本节点。因此,我们生产一个 线框在布局内部。注意,文本已经溢出了正文。我们将在下一步处理这个问题。
显示树的图,树的主体有一个CSS框,段落有一个CSS框,然后在末尾添加一个行框,哪个有一个指向段落CSS框的箭头
因为“世界”不适合我们,我们也没有改变 溢出属性的默认值,引擎向它的父引擎报告它在布局文本时停止的地方。
显示树的图,树的主体有一个CSS框,段落有一个CSS框,现在两个行框附加到末尾
由于父节点收到一个令牌,表示其子节点无法完成所有内容的布局,它复制行框,包括所有的样式,并传递该框的信息以完成布局。布局完成后,浏览器走回盒子树,解决任何 汽车或尚未解析的基于百分比的值。在这张照片里,你可以看到正文和段落现在包含了“Hello world”的所有内容,因为它 高度被设置为 汽车

处理浮点数

现在让我们再复杂一点。我们将采用一个正常的布局,其中有一个按钮说“共享它”,并将其浮动到一段拉丁文本的左侧。浮动本身被认为是“缩小到适合”的上下文。之所以将其称为“收缩到合适”,是因为如果盒子的尺寸是合适的,那么它的内容周围就会缩小汽车。浮动框是匹配这种布局类型的一种框,但是还有很多其他的盒子,如绝对定位盒(包括位置:固定元素)和表单元格汽车的大小,为例。

下面是我们的按钮场景的代码:


       

Lorem ipsum dolor sit amet,consectetur adipiscing elit。Nullam pellentesq

一篇文章的带有CSS框的框树图,一个按钮的CSS框向左浮动,还有一个行框
该过程开始时遵循与“Hello world”示例相同的模式,我要跳到开始处理浮动按钮的地方。
包含CSS框和计算按钮最大和最小宽度的行框的框树图
因为浮动会创建一个新的 块格式化上下文(BFC)是一个缩小到合适的上下文,浏览器执行一种名为 测量内容。在这种模式下,它看起来和其他布局一样,但有一个重要的区别,这是在无限空间中完成的。浏览器在此阶段所做的是按最大和最小的宽度布局BFC树。在这种情况下,它在布局一个带有文本的按钮,所以它最窄的尺寸,包括所有其他CSS框,将是最长单词的大小。最宽,所有的文本都在一行,加上CSS框。 注意:这里按钮的颜色不是文字的。仅供说明之用。
一篇文章的带有CSS框的框树图,一个按钮的CSS框向左浮动,一个直线框,按钮的CSS框现在将最小和最大宽度传回文章的CSS框
现在我们知道最小宽度是86px,最大宽度是115px,我们将此信息传递回父框,让它决定宽度并适当地放置按钮。在这个场景中,有空间适应浮动的最大大小,所以这是按钮的布局。
一个带有两个分支的文章的CSS框的框树图:一个用于向左浮动的按钮的CSS框和一个用于段落的CSS框。文章的CSS框将按钮的最小和最大宽度传递给段落。
为了确保浏览器遵守标准,内容围绕着浮动,的几何形状 文章均。这个几何图形被传递给段落,以便在其布局期间使用。
一个带有两个分支的文章的CSS框的框树图:一个用于向左浮动的按钮的CSS框和一个用于段落的CSS框。这个段落还没有被解析,并且在一行中溢出了父容器。
从这里开始,浏览器遵循与第一个示例相同的布局过程—但是它确保任何内联内容的内联和块的起始位置都在浮动所占用的约束空间之外。
一个带有两个分支的文章的CSS框的框树图:一个用于向左浮动的按钮的CSS框和一个用于段落的CSS框。这一段现在已被分析并分成四行,图中有四个线框来表示这个。
当浏览器继续沿着树向下移动并克隆节点时,它经过约束空间的块位置。这允许在内联方向的内容框的开始处开始文本的最后一行(以及前一行)。然后浏览器回到树上,解决 汽车以及必要时的百分比值。

理解碎片

布局如何工作的最后一个方面是碎片化。如果您曾经打印过网页或使用过CSS多列,然后你利用了碎片化。碎片化是将内容分解成不同的几何形状的逻辑。让我们看看使用CSS多列的同一个例子:


	
       

Lorem ipsum dolor sit amet,consectetur adipiscing elit。耐腐蚀合金nibh奥利奇,tincidunt eget enim et,pellentesque condimentum大笑。艾尼的sollicitudin risus velit,请您原谅我。因此,我取名叫毛利。割喉前前庭

显示主体的CSS框和div的multicol框的框树图
一旦浏览器到达multicol格式化上下文框,它看到它有一组列。
一个框树的图,显示一个CSS框的主体和一个multicol框的div,现在在div下创建了一个fragmentainer CSS框
它沿用了之前类似的克隆模型,并创建一个 fragmentainer使用正确的维度来坚持作者对其列的期望。
一个框树的图,显示一个CSS框的主体和一个multicol框的div,现在,每个列都有一个CSS框,每个列中的每一行都有一个行框
然后,浏览器按照与以前相同的模式尽可能多地排列行。然后浏览器创建另一个fragmentainer并继续完成布局。

绘画

好吧,让我们回顾一下我们现在所处的位置。我们去掉了所有的CSS内容,解析它,将它级联到DOM树中,并完成了布局。但是我们还没有应用颜色,边界,阴影,与添加布图类似的设计处理称为绘画。

绘画基本上是由CSS标准化的,简而言之(你可以把全部的细目都看进去CSS 2.2附录E),你画的顺序如下:

  • 背景;
  • 边界;
  • 和内容。

如果我们从之前的分享按钮开始,它看起来是这样的:

图形显示一个盒子的逐步通过:首先是背景,然后,的内容

一旦完成,它被转换成位图。这是正确的——最终,每个布局元素(甚至文本)都变成了引擎盖下的图像。

有关z - index

现在,我们的大多数网站都不是由单一元素组成的。此外,我们通常希望某些元素出现在其他元素之上。为了实现这一点,我们可以利用……的力量z - index把一种元素叠加在另一种元素上。这就像是我们在设计软件中使用图层的方式,但是唯一存在的层是在浏览器的合成器中。看起来好像我们在创建新的图层z - index,但我们没有那么我们在做什么呢?

我们要做的是创建一个新的堆栈上下文。创建一个新的叠加背景有效地改变绘制元素的顺序。让我们看一个例子:



       
第一项
第二项

没有z - index利用率,上面的文档将按照文档顺序绘制,将“项目2”置于“项目1”之上,但由于z - index,油漆顺序改变让我们一步一步地过每一个阶段,类似于我们之前的布局。

具有表示根堆栈上下文的基本布局的框树的关系图。一个盒子的z指数是1,另一个盒子的z指数是2。
浏览器从根框开始;我们在背景中作画。
相同的布局,但是z-index为1的方框现在正在渲染。
然后浏览器遍历,将文档顺序打乱到较低层次的堆栈上下文(在本例中是“Item 2”),并开始按照上面的相同规则绘制该元素。
相同的布局,但是,z-index为2的框现在呈现在前一个框的顶部
然后它遍历下一个最高的堆栈上下文(在本例中是“Item 1”),并根据CSS 2.2中定义的顺序绘制它。

z - index与颜色无关,只有哪些元素对用户可见,因此,哪些文本和颜色是可见的。

作文

在这个阶段,我们有一个最小的位图,从绘画传递到合成。合成师的工作是创建一个图层,或层,并将位图显示到屏幕上供最终用户查看。

一个合理的问题是,“为什么任何站点都需要多个位图或合成器层?”好,到目前为止我们看过的例子中,我们真的不会。让我们看一个更复杂的例子。假设在一个假设的世界里,Office团队想让Clippy重新上线,他们想让Clippy通过CSS转换来引起注意。

动画Clippy的代码可以像这样:


       

当浏览器读取web开发人员想要在无限循环上动画Clippy时,它有两种选择:

  • 它可以为动画的每一帧回到重绘阶段,并生成一个新的位图发送回合成程序。
  • 或者它可以产生两个不同的位图,并允许合成器只在应用了该动画的层上进行动画本身。

在大多数情况下,浏览器将选择选项2并生成如下内容(在本例中,我有意简化了Word Online生成的层数):

显示根复合层的关系图,在其自己的层上带有Clippy

然后它将在正确的位置重新组合快速位图,并处理脉动动画。这对于性能来说是一个巨大的胜利,因为在许多引擎中,合成器是在它自己的线程上,这允许主线程被解除阻塞。如果浏览器选择上面的选项一,它必须对每一帧进行阻塞才能得到相同的结果,这将对最终用户的性能和响应能力产生负面影响。

显示带有Clippy布局的图表,用图表说明绘制的过程。撰写步骤是循环的。

创造互动的假象

正如我们刚刚学到的,我们取了所有的样式和DOM,并生成一个我们呈现给最终用户的图像。那么,浏览器如何创建交互性的假象呢?Welp,我相信你们已经学到了,所以让我们来看看一个例子,使用我们方便的“分享它”按钮作为一个类比:

按钮{浮动:左;背景:rgb (21032岁的79);填充:3 px 10 px;按钮:悬停{背景:青色;颜色:黑色;}

我们在这里添加的只是一个伪类,它告诉浏览器在用户悬停在按钮上时更改按钮的背景和文本颜色。这回避了一个问题,浏览器如何处理这个问题?

浏览器不断地跟踪各种输入,当这些输入在移动时它会经过一个叫做冲击测试。对于这个示例,这个过程是这样的:

显示命中测试过程的图表。具体过程如下。
  1. 用户将鼠标移到按钮上。
  2. 浏览器触发鼠标移动的事件,并进入hit测试算法,这就提出了一个问题,“老鼠在摸什么盒子?”
  3. 该算法返回链接到我们的“共享它”按钮的框。
  4. 浏览器会问这个问题,“既然有只老鼠在你头顶上盘旋,我该怎么办?”
  5. 它快速地为这个盒子及其子盒子运行样式/级联,并确定,是的,有一个:徘徊伪类,在声明块内具有仅用于绘制的样式调整。
  6. 它将这些样式挂在DOM元素上(正如我们在级联阶段学到的),这是按钮在这种情况下。
  7. 它跳过布局,直接绘制一个新的位图。
  8. 新的位图传递给合成程序,然后传递给用户。

给用户,这有效地创造了互动性的概念,即使浏览器只是将橙色的图像转换成绿色的图像。

果不其然!

希望这消除了CSS如何从大括号到浏览器中呈现像素的一些神秘之处。

在这段旅程中,我们讨论了如何解析CSS,如何计算值,以及级联是如何工作的。然后我们开始讨论布局,绘画,和组成。

现在请继续关注本系列的最后一部分,其中JavaScript语言本身的设计者之一将讨论浏览器如何编译和执行我们的JavaScript。

关于作者

4读者评论

加载评论