You’ve probably heard of floating, absolute and relative positioning but it’s less likely you understand how they work. The information is available, but those specifications are aimed at browser-builders, not beginner CSS coders. It’s properly technical stuff. So with this tutorial I hope to lay out the concept of the flow, and why understanding it will give you a greater grasp of CSS. Lets start at the beginning (after all, I hear that’s a very good place to start!)
Block and Inline level elements
This is probably the hardest concept to get your head around. In terms of CSS, an element can either be displayed ‘Block’ or ‘Inline’. You can change this using the
display property of CSS, for example, setting
display: block on an element makes it follow the block display model (suprising, huh?). Likewise,
display: inline makes an element inline. But what’s the difference?
Block level elements
Block level elements are boxes, essentially. You can size them with
height, give them
backgrounds and they’re useful for positioning elements contained within them. Block level elements can contain any other element.
Inline level elements
Inline level elements, however, you can’t alter the size of. You normally wrap text with them, and so you could tell the text contained within them to have a different
font-weight, or maybe you could do a little bit of
font-style-ing to them, or whatever. Think of inline level elements as bits of text.
It’s easier to see the difference when you start thinking about which elements are which: by default (you can change any of these defaults with
h* (that’s any of the header elements),
li (well, strictly, these follow the display model ‘list-item’ which is identical to ‘block’ except that the element carries a list marker — a bullet or number, normally) and so on are block level, whereas things like
strong are inline (these are all just elements that are used to pick out a bit of text).
img is also inline, although it has not much to do with text.
Onto the flow
Now you have a brief understanding of the different display models, it’s time to introduce the concept of the flow. It’s just that: a concept. A set of laws. It’s not a physical thing, although it’s easy to fall into that thinking trap. The flow dictates how elements follow each other, how they exist next to each other, how they should be displayed.
Block level elements make boxes in the flow. They are always a solid, regular, rectangular shape. This is why you can give them a border, width and height without the browser worrying about funny shapes. Inline level elements don’t make this lovely regular shapes: They could start of regular, but then flow next to a box on the left and be forced over to the right. Here’s a diagram:
As you can see, the inline level element (the text) is all over the place! It has to worm its way between the block level elements. To enable the browser to render this, the inline text is split into ‘line boxes’: a sort of block level box that contains the text of the current line, that doesn’t really exist and can be places next to other block level elements. The line boxes in the diagram above have been outlines in a light blue. So block level elements form nice boxes in the flow, inline ones don’t. It’s also worth noting that block level elements cannot appear next to each other: they will always be on different lines, even if you constrain their widths so they could appear next to each other (this is unless you invoke the float model or positioned model, which I’ll come onto later)
The normal flow is very limited: you can only have block level and inline level elements, these can’t overlay each other, and you can’t have block level elements next to each other. However, you can do something very special with the CSS property
position, which can take one of four values:
static. The first three of those values are the most interesting: they make an element positioned, that is, they remove it from the flow!
How does this work? If you imagine the ‘normal’ flow of all the elements as a sheet of see-through plastic, with all the block level and inline level elements on them, then positioning an element will pop it out of this plastic sheet, onto its very own plastic sheet, which is then overlayed onto the normal flow sheet. When you load up a page with positioned elements you see the result of flattening all these sheets together. Positioning more elements pops them out of the flow into their own flows: there isn’t one mass ‘positioning’ flow. Here’s another diagram:
Each of these ‘position flows’ will just contain the positioned element and its children (unless, of course, these children are positioned themselves!). The four different values that
position can take are pretty irrelevant here:
fixed just change how the co-ordinates of the element are measured from, and
static pops it back into the normal flow; a statically positioned element is no longer positioned.
As positioned elements are on different flows to the static elements, they can (and will) overlay, lie next to, and generall intefere with the static elements. This is useful if you manage it, but can be a source of many problems if you forget you’ve positioned an element.
Another positioning model different to the normal flow is the float model. This is pretty damn complicated, and is misunderstood by most CSS beginners, and indeed the developers of Internet Explorer. I’ll touch briefly on the comlex rules here, but mostly I’ll just explain how it works with respect to the flow.
You can float an element with
float. Here the value that it can take are significant; they are
none (left floated boxes appear as far to the left as possible, right floated as far to the right.
none un-floats the element, analogously to
position: static). Floating an element once more pops it out of the normal flow (into a flow that comes between any positioned flow and the normal one), but this time floating more than one element puts it into the same flow: there is one mass ‘float’ flow. Line boxes in the normal flow adhear the presence of the float in the float flow: if you float a box just before a paragraph the text in that paragraph will shorten itself to make room for the float.
Floats have to have width, otherwise they should (but in fact don’t in most modern browsers) be constrained to zero width. If they can, they will appear next to each other, as will line boxes, unless you set the
clear property on a float or on the parent of the line boxes. The specification on floats is actually worth a read; it explains things quite clearly and contains more diagrams than I’ve used
Elements are split into two main categories: block level and inline level. These can take different CSS properties and are rendered in the flow differently. The flow is a set of rules that governs how elements are rendered next to each other. Positioning an element pops it out of the flow into its own flow, which is then overlayed over the static flow. Floating an element pops it into the float flow with different rules.