webdesign:howbrowserwork
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
webdesign:howbrowserwork [2014/05/20 04:17] – [CSS2 visual model] admin | webdesign:howbrowserwork [2022/10/29 16:15] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== How Browser Work and HTML Language ====== | ||
+ | refer: | ||
+ | [[http:// | ||
+ | ===== Rendering engines ===== | ||
+ | ==== The main flow ==== | ||
+ | {{: | ||
+ | ==== Main flow examples ==== | ||
+ | {{: | ||
+ | **Figure: Webkit main flow** | ||
+ | {{: | ||
+ | |||
+ | **Figure: Mozilla' | ||
+ | ==== Parsing and DOM tree construction ==== | ||
+ | === HTML Parser and DOM === | ||
+ | The job of the HTML parser is to parse the HTML markup into a parse tree. | ||
+ | |||
+ | The output tree - the parse tree is a tree of DOM element and attribute nodes.The DOM has an almost one to one relation to the markup. Example, this markup: | ||
+ | <code html> | ||
+ | < | ||
+ | < | ||
+ | <p> | ||
+ | Hello World | ||
+ | </ | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | Would be translated to the following DOM tree: | ||
+ | {{: | ||
+ | === CSS parsing === | ||
+ | Each CSS file is parsed into a StyleSheet object, each object contains CSS rules. The CSS rule objects contain selector and declaration objects and other object corresponding to CSS grammar. | ||
+ | {{: | ||
+ | ==== Render tree construction ==== | ||
+ | While the DOM tree is being constructed, | ||
+ | |||
+ | Firefox calls the elements in the render tree " | ||
+ | A renderer knows how to layout and paint itself and it's children. | ||
+ | Webkits RenderObject class, the base class of the renderers has the following definition: | ||
+ | <code cpp> | ||
+ | class RenderObject{ | ||
+ | virtual void layout(); | ||
+ | virtual void paint(PaintInfo); | ||
+ | virtual void rect repaintRect(); | ||
+ | Node* node; //the DOM node | ||
+ | RenderStyle* style; | ||
+ | RenderLayer* containgLayer; | ||
+ | } | ||
+ | </ | ||
+ | Each renderer represents a rectangular area usually corresponding to the node's [[# | ||
+ | |||
+ | The box type is affected by the **" | ||
+ | <code cpp> | ||
+ | RenderObject* RenderObject:: | ||
+ | { | ||
+ | Document* doc = node-> | ||
+ | RenderArena* arena = doc-> | ||
+ | ... | ||
+ | RenderObject* o = 0; | ||
+ | |||
+ | switch (style-> | ||
+ | case NONE: | ||
+ | break; | ||
+ | case INLINE: | ||
+ | o = new (arena) RenderInline(node); | ||
+ | break; | ||
+ | case BLOCK: | ||
+ | o = new (arena) RenderBlock(node); | ||
+ | break; | ||
+ | case INLINE_BLOCK: | ||
+ | o = new (arena) RenderBlock(node); | ||
+ | break; | ||
+ | case LIST_ITEM: | ||
+ | o = new (arena) RenderListItem(node); | ||
+ | break; | ||
+ | ... | ||
+ | } | ||
+ | |||
+ | return o; | ||
+ | } | ||
+ | </ | ||
+ | === The render tree relation to the DOM tree === | ||
+ | he renderers correspond to the DOM elements, but the relation is not one to one. | ||
+ | * **Non visual DOM elements** will not be inserted in the render tree. An example is the " | ||
+ | * Also elements whose **display attribute** was assigned to **" | ||
+ | * There are DOM elements which correspond to several visual objects. These are usually elements with complex structure that cannot be described by a single rectangle. For example, the **" | ||
+ | * Some render objects correspond to a DOM node but not in the same place in the tree. [[# | ||
+ | {{: | ||
+ | |||
+ | === Style Computation === | ||
+ | Building the render tree requires calculating the visual properties of each render object. This is done by calculating the style properties of each element. | ||
+ | == Firefox rule tree == | ||
+ | Firefox has two extra trees for easier style computation - the rule tree and style context tree. Webkit also has style objects but they are not stored in a tree like the style context tree, only the DOM node points to its relevant style. | ||
+ | |||
+ | {{: | ||
+ | **Figure: | ||
+ | The style contexts contain end values. The values are computed by applying all the matching rules in the correct order and performing manipulations that transform them from logical to concrete values. | ||
+ | |||
+ | == Computing the style contexts using the rule tree == | ||
+ | |||
+ | Lets see an example: Suppose we have this HTML | ||
+ | <code html> | ||
+ | < | ||
+ | < | ||
+ | <div class=" | ||
+ | < | ||
+ | this is a <span class=" | ||
+ | this is also a | ||
+ | <span class=" | ||
+ | </ | ||
+ | </ | ||
+ | <div class=" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | And the following rules: | ||
+ | - div {margin: | ||
+ | - .err {color:red} | ||
+ | - .big {margin-top: | ||
+ | - div span {margin-bottom: | ||
+ | - #div1 {color: | ||
+ | - #div2 {color: | ||
+ | To simplify things let's say we need to fill out only two structs - the color struct and the margin struct. The color struct contains only one member - the color The margin struct contains the four sides. | ||
+ | |||
+ | The resulting rule tree will look like this (the nodes are marked with the node name : the # of rule they point at): | ||
+ | |||
+ | {{: | ||
+ | **Figure: The rule tree** | ||
+ | |||
+ | The context tree will look like this (node name : rule node they point to): | ||
+ | |||
+ | {{: | ||
+ | **Figure: The context tree** | ||
+ | |||
+ | ==== Painting ==== | ||
+ | === The painting order === | ||
+ | The stacking order of a block renderer is: | ||
+ | - background color | ||
+ | - background image | ||
+ | - border | ||
+ | - children | ||
+ | - outline | ||
+ | ==== CSS2 visual model ==== | ||
+ | === CSS Box model === | ||
+ | Each box has a content area (e.g., text, an image, etc.) and optional surrounding padding, border, and margin areas. | ||
+ | |||
+ | {{: | ||
+ | Each node generates 0..n such boxes.\\ | ||
+ | All elements have a " | ||
+ | Examples: | ||
+ | block - generates a block box. | ||
+ | inline - generates one or more inline boxes. | ||
+ | none - no box is generated. | ||
+ | The default is inline but the [[# | ||
+ | |||
+ | === Positioning scheme === | ||
+ | There are three schemes: | ||
+ | * Normal - the object is positioned according to its place in the document - this means its place in the render tree is like its place in the dom tree and layed out according to its box type and dimensions | ||
+ | * Float - the object is first layed out like normal flow, then moved as far left or right as possible | ||
+ | * Absolute - the object is put in the render tree differently than its place in the DOM tree | ||
+ | |||
+ | The positioning scheme is set by the " | ||
+ | * static and relative cause a normal flow | ||
+ | * absolute and fixed cause an absolute positioning | ||
+ | |||
+ | === Box types === | ||
+ | **Block box**: forms a block - have their own rectangle on the browser window.\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | **Inline box**: does not have its own block, but is inside a containing block.\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | Blocks are formatted vertically one after the other. Inlines are formatted horizontally.\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | Inline boxes are put inside lines or "line boxes" | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | === Position === | ||
+ | == Relative == | ||
+ | Relative positioning - positioned like usual and then moved by the required delta.\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | == Floats == | ||
+ | A float box is shifted to the left or right of a line. The interesting feature is that the other boxes flow around it The HTML:\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | == Absolute and fixed == | ||
+ | The layout is defined exactly regardless of the normal flow. The element does not participate in the normal flow. The dimensions are relative to the container. In fixed - the container is the view port.\\ | ||
+ | {{: | ||
+ | **Figure: | ||
+ | |||
+ | Note - the fixed box will not move even when the document is scrolled! | ||
+ | |||
+ | === Layered representation === | ||
+ | It is specified by the z-index CSS property. It represents the 3rd dimension of the box, its position along the "z axis". | ||
+ | |||
+ | The boxes are divided to stacks (called stacking contexts). In each stack the back elements will be painted first and the forward elements on top, closer to the user. In case of overlap the will hide the former element. | ||
+ | |||
+ | The stacks are ordered according to the z-index property. Boxes with " | ||
+ | |||
+ | Example: | ||
+ | <code html> | ||
+ | <STYLE type=" | ||
+ | div { | ||
+ | position: absolute; | ||
+ | left: 2in; | ||
+ | top: 2in; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | <DIV | ||
+ | | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | The result will be this:\\ | ||
+ | {{: | ||
+ | === Default style sheet for HTML 4 === | ||
+ | <code html> | ||
+ | html, address, | ||
+ | blockquote, | ||
+ | body, dd, div, | ||
+ | dl, dt, fieldset, form, | ||
+ | frame, frameset, | ||
+ | h1, h2, h3, h4, | ||
+ | h5, h6, noframes, | ||
+ | ol, p, ul, center, | ||
+ | dir, hr, menu, pre { display: block; unicode-bidi: | ||
+ | li { display: list-item } | ||
+ | head { display: none } | ||
+ | table { display: table } | ||
+ | tr { display: table-row } | ||
+ | thead { display: table-header-group } | ||
+ | tbody { display: table-row-group } | ||
+ | tfoot { display: table-footer-group } | ||
+ | col { display: table-column } | ||
+ | colgroup | ||
+ | td, th { display: table-cell } | ||
+ | caption | ||
+ | th { font-weight: | ||
+ | caption | ||
+ | body { margin: 8px } | ||
+ | h1 { font-size: 2em; margin: .67em 0 } | ||
+ | h2 { font-size: 1.5em; margin: .75em 0 } | ||
+ | h3 { font-size: 1.17em; margin: .83em 0 } | ||
+ | h4, p, | ||
+ | blockquote, ul, | ||
+ | fieldset, form, | ||
+ | ol, dl, dir, | ||
+ | menu { margin: 1.12em 0 } | ||
+ | h5 { font-size: .83em; margin: 1.5em 0 } | ||
+ | h6 { font-size: .75em; margin: 1.67em 0 } | ||
+ | h1, h2, h3, h4, | ||
+ | h5, h6, b, | ||
+ | strong | ||
+ | blockquote | ||
+ | i, cite, em, | ||
+ | var, address | ||
+ | pre, tt, code, | ||
+ | kbd, samp { font-family: | ||
+ | pre { white-space: | ||
+ | button, textarea, | ||
+ | input, select | ||
+ | big { font-size: 1.17em } | ||
+ | small, sub, sup { font-size: .83em } | ||
+ | sub { vertical-align: | ||
+ | sup { vertical-align: | ||
+ | table { border-spacing: | ||
+ | thead, tbody, | ||
+ | tfoot { vertical-align: | ||
+ | td, th, tr { vertical-align: | ||
+ | s, strike, del { text-decoration: | ||
+ | hr { border: 1px inset } | ||
+ | ol, ul, dir, | ||
+ | menu, dd { margin-left: | ||
+ | ol { list-style-type: | ||
+ | ol ul, ul ol, | ||
+ | ul ul, ol ol { margin-top: 0; margin-bottom: | ||
+ | u, ins { text-decoration: | ||
+ | br: | ||
+ | center | ||
+ | :link, :visited { text-decoration: | ||
+ | : | ||
+ | |||
+ | /* Begin bidirectionality settings (do not change) */ | ||
+ | BDO[DIR=" | ||
+ | BDO[DIR=" | ||
+ | |||
+ | *[DIR=" | ||
+ | *[DIR=" | ||
+ | |||
+ | @media print { | ||
+ | h1 { page-break-before: | ||
+ | h1, h2, h3, | ||
+ | h4, h5, h6 { page-break-after: | ||
+ | ul, ol, dl { page-break-before: | ||
+ | } | ||
+ | </ |