One thing I never really understood about CSS and HTML was how display layout actually works. All of the tutorials and documents I’ve encountered felt to me like the end of a long game of telephone: how things work was garbled, and replaced with a list of half-baked recipes that sort of worked some of the time.
But after spending the last few weeks in a deep dive in the CSS specifications I’ve figured out a few things which I wanted to share here.
At the top of the visual formatting model is a trio of CSS properties which control how a piece of HTML is presented to the user–including if the contents are in a block or is wrapped like text, if it floats to the left or to the right, or if it floats around on the screen, are the following properties:
- Display which indicates how a piece of HTML is displayed.
- Position which indicates how a box is positioned within its parent box or within the page.
- Float which indicates if a cell should float to the left or the right of its parent box.
These three properties are probably the most important properties in determining how a piece of HTML is displayed on the screen. In fact, an entire chapter of the CSS2 spec (on which CSS3 is based) is devoted to these three properties and how they interact.
In fact, they’re so important that there is an algorithm for resolving conflicts between these three properties.
From these three properties we determine what other HTML properties are valid and how they work.
Now on top of this model we also have the box dimensions. Everything within HTML ultimately renders to a box: an inline box (which may represent a run of text that can be word wrapped) or into a block–a rectangular region like an image or a table.
All boxes including inline text is subject to the box dimension properties. This has the interesting side effect that you could (for example) extend a box around a bunch of words and have those boxes subject to word wrapping.
When considering display properties, there are only a handful which are significant. (The rest revolve around table formatting.)
- Block causes a chunk of HTML to be presented as a box. A box can contain inline flowed text (such as a paragraph), or it can contain a bunch of other boxes, which are generally stacked top to bottom.
- Inline which represents inline objects positioned horizontally on the screen, such as inline text. If you want to show a small image inline with text, you’d set ‘display:inline’ on the image tag.
- None causes an object not to appear on the screen.
- inline-block allows you to format a block of content and present that content inline when formatting text. For example, you can use an inline block to display a fraction.
The float property is relatively self-evident. But the position property less so.
As far as I can figure, the position properties are:
- static uses normal formatting; the box is laid out according to the default rules.
- fixed positions the box on the screen in absolute coordinates. (A fixed box can be fixed to the top of the screen, for example.)
- absolute positions the box at a specified location relative to the parent box.
- relative marks an object as being repositionable after it is placed according to normal layout rules.
The “absolute”, “relative” and “fixed” rules have a second property in that they define the container block for children with
position: absolute. Absolute positioned elements and relative positioned elements are positioned relative to their location inside the position flow; the only difference is that absolute positioned elements are not first laid out using normal formatting. (Source)
Putting all this together, this allows you to do things like float text relative to other text in a paragraph, such as:
This is a — test.
It’s interesting that these three properties are the root properties in the layout algorithm, yet they seem to be treated as if they were just incidental (and apparently not well understood) properties in everything I’ve read.