WebCore Rendering I – The Basics

转载 2011年01月11日 13:53:00

WebCore Rendering I – The Basics

Posted by Dave Hyatt on Wednesday, August 8th, 2007 at 5:34 pm

This is the first of a series of posts designed to help people interested in hacking on WebCore’s rendering system. I’ll be posting these articles as I finish them on this blog, and they will also be available in the documentation section of the Web site.

The DOM Tree

A Web page is parsed into a tree of nodes called the Document Object Model (DOM for short). The base class for all nodes in the tree is Node.


Nodes break down into several categories. The node types that are relevant to the rendering code are:

  • Document – The root of the tree is always the document. There are three document classes, DocumentHTMLDocument and SVGDocument. The first is used for all XML documents other than SVG documents. The second applies only to HTML documents and inherits from Document.
    The third applies to SVG documents and also inherits from Document.



  • Elements – All of the tags that occur in HTML or XML source turn into elements. From a rendering perspective, an element is a node with a tag name that can be used to cast to a specific subclass that can be queried for data that the renderer needs.


  • Text – Raw text that occurs in between elements gets turned into text nodes. Text nodes store this raw text, and the render tree can query the node for its character data.


The Render Tree

At the heart of rendering is the render tree. The render tree is very similar to the DOM in that it is a tree of objects, where each object can correspond to the document, elements or text nodes. The render tree can also contain additional objects that have no corresponding DOM node.

The base class of all render tree nodes is RenderObject.


The RenderObject for a DOM node can be obtained using the renderer() method on Node.

RenderObject* renderer() const

The following methods are most commonly used to walk the render tree.

RenderObject* firstChild() const;
RenderObject* lastChild() const;
RenderObject* previousSibling() const;
RenderObject* nextSibling() const;

Here is an example of a loop that walks a renderer’s immediate children. This is the most common walk that occurs in the render tree code.

for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {

Creating the Render Tree

Renderers are created through a process on the DOM called attachment. As a document is parsed and DOM nodes are added, a method called attach gets called on the DOM nodes to create the renderers.

void attach()

The attach method computes style information for the DOM node. If the display CSS property for the element is set to none or if the node is a descendant of an element with display: none set, then no renderer will be created. The subclass of the node and the CSS display property value are used together to determine what kind of renderer to make for the node.

Attach is a top down recursive operation. A parent node will always have its renderer created before any of its descendants will have their renderers created.

Destroying the Render Tree

Renderers are destroyed when DOM nodes are removed from the document or when the document gets torn down (e.g., because the tab/window it was in got closed). A method calleddetach gets called on the DOM nodes to disconnect and destroy the renderers.

void detach()

Detachment is a bottom up recursive operation. Descendant nodes will always have their renderers destroyed before a parent destroys its renderer.

Accessing Style Information

During attachment the DOM queries CSS to obtain style information for an element. The resultant information is stored in an object called a RenderStyle.


Every single CSS property that WebKit supports can be queried via this object. RenderStyles are reference counted objects. If a DOM node creates a renderer, then it connects the style information to that renderer using the setStyle method on the renderer.

void setStyle(RenderStyle*)

The renderer adds a reference to the style that it will maintain until it either gets a new style or gets destroyed.

The RenderStyle can be accessed from a RenderObject using the style() method.

RenderStyle* style() const

The CSS Box Model

One of the principal workhorse subclasses of RenderObject is RenderBox. This subclass represents objects that obey the CSS box model. These include any objects that have borders, padding, margins, width and height. Right now some objects that do not follow the CSS box model (e.g., SVG objects) still subclass from RenderBox. This is actually a mistake that will be fixed in the future through refactoring of the render tree.

This diagram from the CSS2.1 spec illustrates the parts of a CSS box. The following methods can be used to obtain the border/margin/padding widths. The RenderStyle should not be used unless the intent is to look at the original raw style information, since what is actually computed for the RenderObject could be very different (especially for tables, which can override cell padding and have collapsed borders between cells).

int marginTop() const;
int marginBottom() const;
int marginLeft() const;
int marginRight() const;

int paddingTop() const;
int paddingBottom() const;
int paddingLeft() const;
int paddingRight() const;

int borderTop() const;
int borderBottom() const;
int borderLeft() const;
int borderRight() const;

The width() and height() methods give the width and height of the box including its borders.

int width() const;
int height() const;

The client box is the area of the box excluding borders and scrollbars. Padding is included.

int clientLeft() const { return borderLeft(); }
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;

The term content box is used to describe the area of the CSS box that excludes the borders and padding.

IntRect contentBox() const;
int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }

When a box has a horizontal or vertical scrollbar, it is placed in between the border and the padding. A scrollbar’s size is included in the client width and client height. Scrollbars are not part of the content box. The size of the scrollable area and the current scroll position can both be obtained from the RenderObject. I will cover this in more detail in a separate section on scrolling.

int scrollLeft() const;
int scrollTop() const;
int scrollWidth() const;
int scrollHeight() const;

Boxes also have x and y positions. These positions are relative to the ancestor that is responsible for deciding where this box should be placed. There are numerous exceptions to this rule, however, and this is one of the most confusing areas of the render tree.

int xPos() const;
int yPos() const;

WebCore Rendering III – Layout Basics

WebCore Rendering III – Layout Basics
  • Max__Payne
  • Max__Payne
  • 2011年01月11日 13:54
  • 511

WebCore Rendering I --- the basic

原文:http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/ 一下是翻译版本,后面还有对照版本。  这是一系列文章中的第一篇,...
  • bertzhang
  • bertzhang
  • 2011年08月30日 13:39
  • 1496

WebCore Rendering

  • liumf2005
  • liumf2005
  • 2013年03月22日 13:50
  • 414

WebCore Rendering V - Floats

原文:http://www.webkit.org/blog/118/webcore-rendering-v-floats/ 译文: float是一个renderer可以使得对象全部放置在段落的...
  • bertzhang
  • bertzhang
  • 2011年09月01日 15:18
  • 840

WebCore Rendering 1 - 基础

DOM树(The DOM Tree)         网页的HTML源代码会被解析成一棵名叫文档对象模型(Document Object Mode,DOM)的,由各个节点组成的树。树节点的基类为No...
  • jordanxinwang
  • jordanxinwang
  • 2012年05月27日 16:48
  • 463

WebCore Rendering 5 - 浮动

  • jordanxinwang
  • jordanxinwang
  • 2012年09月09日 15:52
  • 529

WebCore Rendering V – Floats

WebCore Rendering V – Floats
  • Max__Payne
  • Max__Payne
  • 2011年01月11日 13:56
  • 405

ffmpeg学习二:《FFmpeg Basics》读书笔记(上)

为了更好的理解ffmpeg工程,官方推荐了一本书:《FFmpeg Basics》。完整的读完这本书,应该对这个工程能有一个基本的理解了。本菜英文不好,姑且从这本书中提炼出一些比较常用的知识,做个笔记吧...
  • u011913612
  • u011913612
  • 2016年11月29日 16:48
  • 1341

WebCore Rendering 3 - 排版基础

当渲染树节点首次创建并加入到渲染树时,它还没有任何位置和大小信息。计算各个盒(Box)的位置和大小的过程即为排版(layout)。每一个渲染树对象都有一个排版方法。 void layout() 排...
  • jordanxinwang
  • jordanxinwang
  • 2012年08月26日 15:49
  • 581

WebCore Rendering II -- Blocks and Inlines

原文链接:http://www.webkit.org/blog/115/webcore-rendering-ii-blocks-and-inlines/ 译文:  Posted by Dave H...
  • bertzhang
  • bertzhang
  • 2011年08月31日 14:06
  • 977
您举报文章:WebCore Rendering I – The Basics