xmouse

What is ‘the flow’?

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 width and height, give them borders, 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 display), div, p, h* (that’s any of the header elements), ul, ol, 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 span, a, em and 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:

Diagram showing how inline level elements don't have solid boxes in the flow

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)

Positioning

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: absolute, relative, fixed and 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:

Diagram showing how positioned elements each have their own flow

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: absolute, relative and 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.

Floating

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 left, right and 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 :)

Conclusion

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.