CSS Layout and Formatting

    Adam Roberts
    Share

    While CSS1 didn’t have much to offer for the graphical layout of documents, CSS2 has introduced several new properties for layout, and CSS3 will probably add even more. Although CSS still doesn’t provide total control over the page layout, it’s far more powerful than the old-school technique of using layout tables and presentational markup.

    A web browser typically reads and renders HTML documents. This happens in two phases: the parsing phase and the rendering phase.

    During the parsing phase, the browser reads the markup in the document, breaks it down into components, and builds a document object model (DOM) tree.

    Consider this example HTML document:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "https://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <title>Widgets</title>
      </head>
      <body>
        <h1>Widgets</h1>
        <p>Welcome to Widgets, the number one company
        in the world for selling widgets!</p>
      </body>
    </html>

    The above HTML document can be visualized as the DOM tree in the graph below (in which the text nodes have been omitted for clarity).
    layout_dom-tree
    Each object in the DOM tree is called a node. There are several types of nodes, including element nodes and text nodes. At the top of the tree is a document node, which contains an element node called the root node; this is always the html element in HTML and XHTML documents, and it branches into two child element nodes—head and body—which then branch into other children.

    A child node is structurally subordinate to its parent node. In HTML terms, this means that the child’s tags are nested inside the tags of the parent. For example, we can see in the above graph that the h1 element is a child node of the body element and the body element is the parent node of the h1 element. A node can be called a descendant node if it’s a child, grandchild, and so on, of another node. A node can be called an ancestor node if it’s a parent, grandparent, and so on, of another node. For example, the h1 element is a descendant node of the html element, and the html element is an ancestor node of the h1 element. Nodes that have the same parent are called siblings. The h1 and p elements are sibling nodes.

    When the DOM tree has been constructed, and any CSS style sheets have been loaded and parsed, the browser starts the rendering phase. Each node in the DOM tree will be rendered as zero or more boxes.

    Just as there are block-level elements and inline elements in HTML, there are block boxes and inline boxes in CSS. In fact, there are several other box types, but they can be seen as subtypes of the block and inline boxes.

    A CSS box is always rectangular. It has four sides with a 90° angle between each of them.

    From a somewhat simplified perspective, we can say that it’s the user agent style sheet which specifies that block-level HTML elements generate block boxes, while inline-level HTML elements generate inline boxes. We can, of course, use the display property to change the type of the box generated for any element.

    CSS does not, however, affect the markup in any way. The separation into block-level and inline elements in HTML is specified in the HTML document type definition, and cannot be changed. For example, setting the display property to block for a span element doesn’t allow us to nest an h1 element inside it, because the HTML document type definition forbids it.

    In this Section