This article includes some assumed knowledge on the box model. If you don't know what the box model is, you can read my article about that here.
Document flow is the arrangement of page elements, as defined by CSS positioning statements, and the order of HTML elements. this is to say, how each element takes up space and how other elements position themselves accordingly.
So, what does this mean exactly? Well, lets break it down. There are three main ways elements are positioned:
- Display types
HTML elements are initially positioned by their display type. This display type determines things like whether other elements are able to sit beside them, and how padding, margin and other CSS properties affect it. The two most important display types are:
There are many others, which you can find more about at W3's specification for CSS Display Property.
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse. — W3 Spec
Understand that? Me neither. Essentially, a block can't have things sit next to it. Block elements placed after each other appear vertically, one after the other. Even if a block element has the CSS property of width set on it, elements defined after it will be placed below it, and elements defined before it will be placed above it.
In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. — W3 Spec
This ones a bit easier to digest. Inline blocks respect their siblings, and allow them to sit horizontally. They're only as wide as their content. They can also be vertically aligned using the vertical-align property, as opposed to block-level elements which can't. However unlike the block element, they are restricted in many of the CSS properties they can employ.
A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or "floated" or "floating" box) is that content may flow along its side (or be prohibited from doing so by the 'clear' property). Content flows down the right side of a left-floated box and down the left side of a right-floated box. — W3 Spec
Floats are CSS property which you can apply to a block level element to push it to either the left or the right boundary of its parent's box. This is very useful, as it allows you to use all the benefits of what a block-level element can offer, whilst getting around the major limitation of not being able to place block-level elements horizontal to each other. However, there are trade off's to using floats.
Floated elements are taken out of the normal document flow. A well known issue is when multiple child elements are floated, resulting in a loss of height for the parent. Normally, a parent's height and width will stretch to fit the content, however with floated content this is not the case. The parent container's height and width will not be modified by floated elements. Thankfully, this is a well known issue and has many fixes, such as the clearfix . For more on the clearfix, you can read about it here. A lot of grid systems are designed using floats, which are the architectural backbone of a website.
There are several positioning values which can be applied to elements. The initial value applied to all elements is "static", an in-flow type, which we will talk about later.
Value: static | relative | absolute | fixed | inherit
Position offset properties
Properties: top | right | bottom | left
There are two groups of positioning properties. In flow, and out-of-flow.
There are two in flow position values, which are static and relative.
Static As mentioned earlier, elements by default use the in-flow value of "static". This means they behave normally, as per their display type layout. They also don't interact with out-of-flow elements. They are unaffected by position offset properties (top, right, bottom, left).
Relative position is very similar to static, but the major difference is that they're able to interact with out-of-flow elements. A relatively positioned element can be used as a container for out-of-flow children elements. The out-of-flow positioned elements will respect the box boundaries of the relatively positioned element. Cool, right? Relatively positioned elements, unlike static, can also use position offset properties to move it. When using these properties, the relatively positioned element's box will still take up the space of its original position, but the content will be shifted out-of-flow.
There are two out-of-flow position values, which are absolute and fixed.
In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block. — W3 Spec
Absolute positioned elements brings in the concept of layers. Imagine elements are just different pieces of paper. You can stack those pieces of paper on top of each other, so that one piece overlaps another. The same concept applies to HTML elements. Using a property known as z-index, you can control which elements overlap others. The W3 specification also mentions that it respects a containing block. This block is not its direct parent. As mentioned earlier, all HTML elements that are statically positioned, don't affect out-of-flow elements. By default, this containing block is the body tag. If you wish to make an HTML element a containing block, it must have a position of anything but static (fixed, relative, or absolute).
Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport. — W3 Spec
Pretty straightforward! The viewport is the browser window. That is to say, unlikely absolutely positioned elements, a fixed position element will not respect any parent containers with fixed/absolute/relative positioning. The only parent is respects is the browser window itself. This is great for when you want something to stay on the page, as all fixed positioned elements will stay on the page while you scroll.
And that wraps up the explanation of the document model! This blog post will invariably be adjusted to include informative images, examples and some exercises (when I can be bothered).