WebCore 渲染 V – 浮动

“浮动”(float)是一种渲染器,旨在将其所在段落中的所有内容向左或向右移动。段落中的文本行会围绕浮动对象流动,从而避开它。你可以在本段中看到一个浮动示例。右上角有一个紫色框。请注意本段中的所有文本是如何避开这个浮动元素的。

上面紫色浮动元素的声明方式如下:

<div style="float:right; width:50px; height:50px; background-color:purple; margin-left: 5px"></div>

还有一些 HTML 构造隐含了 CSS 浮动行为。例如,img 元素的 align 属性可用于浮动图像。

<img align=left src="...">

一个浮动元素可以跨越多个段落。在这个例子中,尽管浮动元素是在本段中声明的,但它足够高,会从本段突出到下一段。

由于浮动元素可以有效地与多个块相交,WebCore 使用块流上的一个“浮动对象列表”(floating objects list)来跟踪所有侵入该块边界的浮动渲染器。因此,一个浮动元素可以存在于多个块流的浮动对象列表中。行布局必须知道浮动元素的位置,以便在必要时缩小文本行以避开这些浮动元素。通过将给定块的所有相关浮动元素立即在其浮动对象列表中可用,该块可以轻松知道它需要避开的浮动元素的位置。

浮动对象列表包含以下数据结构:

    struct FloatingObject {
        enum Type {
            FloatLeft,
            FloatRight
        };

        FloatingObject(Type type)
            : node(0)
            , startY(0)
            , endY(0)
            , left(0)
            , width(0)
            , m_type(type)
            , noPaint(false)
        {
        }

        Type type() { return static_cast<type>(m_type); }

        RenderObject* node;
        int startY;
        int endY;
        int left;
        int width;
        unsigned m_type : 1; // Type (left or right aligned)
        bool noPaint : 1;
    };

如你所见,这个结构有效地包含一个矩形(顶部、底部、左侧和宽度)。每个列表项都有自己独立于浮动对象位置和大小的位置和大小,原因是这些坐标位于拥有浮动对象列表的块的空间中。这样,每个块都可以轻松查询浮动元素在其自身坐标空间中的位置,而无需进行大量转换。

此外,浮动元素的边距也包含在列表项矩形中,因为文本行不仅仅避开浮动元素的边框。它们避开浮动元素的边距框。这很重要,这样浮动元素就可以用额外的空间填充,以避免文本行紧贴其边缘。

以下方法在浮动对象列表上操作:

void insertFloatingObject(RenderObject*);
void removeFloatingObject(RenderObject*);
void clearFloats();
void positionNewFloats();

前两个函数是相当不言自明的。它们用于将特定的浮动元素添加和从块的浮动对象列表中移除。clearFloats 将删除块的浮动对象列表中的所有对象。

当对象插入列表时,它最初是未定位的。其垂直位置设置为 -1positionNewFloats 方法由布局调用以放置所有浮动元素。CSS 为浮动元素的允许位置规定了一系列规则。正是这个方法确保了所有这些规则都得到遵守。

还有更多处理浮动元素的辅助方法。我将在未来的文章中更详细地讨论块和行布局时介绍这些方法。

清除

CSS 提供了一种方式,让对象可以指定它们应该位于所有左浮动元素、所有右浮动元素或所有浮动元素之下。clear 属性指定了此行为,其值可以是 noneleftrightboth

本段位于上一段的蓝色浮动元素之下,因为它指定了 clear: left。清除是在块和行布局期间计算和应用的。clear 属性也可以应用于浮动元素,以确保浮动元素最终位于所有先前的浮动元素之下(同样,可以是左浮动、右浮动或两种类型的浮动)。