Introduction
It took me a good while (and some down-voted StackOverflow i.e. questions) for me to understand what I was asking exactly. I'd heard the term Normal Flow used when describing how HTML layout engines position elements on the screen. I'd also read that there are many of these flows, which was confusing because e couldn't find any mention of any flow other than the normal one.
After a lot of Binging and Googling and shouting into a bucket I did finally find what I was looking for, and understood why people were looking at me like I was dense when I was asking what the non-normal flows might be.
The critical bit of information I was missing was in the CSS 2.2 specification in Section 9: Visual formatting model which talks about positioning schemes. it say that there are three kinds:
- Normal flow
- Float
- Absolute
That explains why I was getting no luck looking for flows that weren't normal. Firstly, they're called positioning schemes, not flows and secondly, none of the others members of it even have the work flow in their name.
Normal Flow
The default positioning scheme.
Normal flow is concerned with whether an element is block
or inline
. inline
elements are positioned along a line until it reaches the end and can't fit another, then it starts a fresh line and carries on. block
elements won't share a line with anything else, as such they will always create a new line appear one after another down the page at the start of each line.
The following shows only inline
elements.
There was a table set out under a tree in front of the house, and the March Hare and the Hatter were having tea at it: a Dormouse was sitting between them, fast asleep, and the other two were using it as a cushion, resting their elbows on it, and talking over its head. 'Very uncomfortable for the Dormouse,' thought Alice; 'only, as it's asleep, I suppose it doesn't mind.'
The text formatting elements and the image flow across the line, starting a new one as needed. Even though the image is larger than the text it still does it and will increase the height of the line to accommodate it.
Compare this with block elements:
- 'Have some wine,' the March Hare said in an encouraging tone.
- Alice looked all round the table, but there was nothing on it but tea. 'I don't see any wine,' she remarked.
- 'There isn't any,' said the March Hare.
- 'Then it wasn't very civil of you to offer it,' said Alice angrily.
- 'It wasn't very civil of you to sit down without being invited,' said the March Hare.
Each list item is on it's own line, regardless of whether there was room for it next to the existing text. in fact, block
elements won't share the line with trailing inline items as well as previous ones.
Alice looked all round the table, but there was nothing on it but tea. 'I don't see any wine,' she remarked.
- 'Have some wine,' the March Hare said in an encouraging tone
Relative positioning
Consider this inline set on boxes all in the normal flow:
We can move elements around within the normal flow if we give their position
property the value of relative
. This doesn't affect the normal flow at all, but does cause the element to be displayed offset to its original position.
Importantly notice that the space it would have taken up is still being reserved for it. Even though it's visual properties have changed it's affect on the normal flow has not changed. This is very different to the other two positioning schemes, both of which remove the element from the normal flow.
Floating
We float an element by setting its float
is calculated as something other than none
. It will cause the element to go as far to the edge of it's containing element as it can, stacking next to any other floated elements that might be there. The elements remaining in the normal flow then try to fit themselves around it.
Left float
Right float
Left and Right Floats
Here we've floated boxes C
, E
and F
to the left. Notice that each goes to the left of it's own line, E
and F
stack onto each other
Floating larger objects
So far floats are boring, their power becomes apparent when we mix floats with smaller elements like text. Here we're floating two images of the the March Hare.
'Not the same thing a bit!‘ said the Hatter. 'You might just as well say that 'I see what I eat' is the same thing as 'I eat what I see'!&'
'You might just as well say,' added the March Hare, 'that 'I like what I get' is the same thing as 'I get what I like'!‘
'You might just as well say,' added the Dormouse, who seemed to be talking in his sleep, 'that 'I breathe when I sleep' is the same thing as 'I sleep when I breathe'!';
The text just flows within its new boundaries.
Absolute positioning
For an element to be absolutely positioned the position
property must have a value of either:
absolute
fixed
both of these values will remove the element from the normal flow, though in slightly different ways.
Absolute position
(The word 'absolute' can refer to both the category of properties that remove an element from the normal flow or the specific value 'absolute', a potential value of position. It's a confusingly overloaded word).
This will position an element relative to the top left corner of the first parent container who's position
value except static
. It's a bit of a strange one conceptually and I admit that I don't quite know why it was designed this way (if anyone knows, please let me know @BanksySan).
I've added a div
around boxes B
to D
and set its position
value to relative
. Just to highlight it I've shifted the container down and to the left and made the contained boxes green.
If I now set box C
to have a position
of absolute
then we can see the effect.
Two important things have happened here, box firstly C
has been removed from the normal flow so box D
has shifted up next to B
; secondly box C
has moved down and right. What's particularly important to notice though is that it has moved relative to the container box. It's relative to this because we changed the container box's position from static
. If we removed that property then the box would position itself relative to the next parent it found that wasn't statically positioned or, if nothing's found, relative to the top left of the document itself.
Fixed position
Fixed positioning is very similar to absolute positioning with one important difference. Rather that positioning the element in relation to any other element it instead positions it in relation to the view port itself.
The box above is actually an iFrame, so is an isolated viewport. Try scrolling down and up, you'll notice that box C
remains where it is and the elements in the normal flow ignore it.
Conclusion
There are three positioning schemes. These are:
- Normal Flow
- Absolute positioning
- Floating
Normal flow involves two categories of element.
- Inline
- Will layout vertically (left‑to‑right or right‑to‑right depending on your culture settings), starting a new line once the current line can't fit the next token on it. Line height expends per line as required to accommodate everything on the line.
- Block
- Will always use an entire line (i.e. will not share a line with either another block or inline element) and will appear at the start of the line (left or right depending on culture). A block element has a
height
andwidth
which can be manipulated via CSS.
Both absolute positioning and floating will remove the element from the normal flow. In the case of absolute positioning (position: absolute
or position: fixed
) the normal flow elements are no longer affected by the element at all and so will flow as if the element didn't exist. Floated elements are removed from their position in the normal flow and shifted to the left or right, elements in normal flow do interact with them and will attempt to flow around them. Floated elements will also interact with each other, stacking up next to each other.
The question you're probably asking now (and rightfully so) is how do elements removed from the normal flow interact with each other?. The keyword to Bing Google with is
Thanks for reading.
Give me a shout @BanksySan.