If you’ve come to grips with CSS-based layouts, then it’s likely that you’re using floats as the primary means to layout your pages. Maybe you’ve even started to experiment with some of CSS’s far-future layout techniques, in hopes that browser support for them improves.
One aspect of CSS layouts that will likely be around for some time yet is CSS positioning. That is, using CSS’s position
property. In this post, I’ll cover CSS positioning in detail and I hope you’ll come away from this with some more options in your CSS layouts.
Contents
Statically Positioned Elements
The first thing I’ll cover here is elements that are positioned statically. Here’s how this is done:
.example { position: static; }
In most cases, however, this is actually completely unnecessary. The value static
is the default, or initial value, for the position
property. This means that, if you don’t declare a position value on an element, it starts out as “static”. So what does this value mean in terms of the element’s behaviour?
According to the spec, a statically positioned element is a “normal box”, laid out with what is referred to as normal flow. This means that a static element will be positioned based on its order in relation to other elements, flowing normally, with a change in behaviour depending on whether or not the element is block or inline. Other factors may also affect how a static element behaves, but, generally speaking, a static element’s behaviour is as straightforward as it gets.
Relatively Positioned Elements
Another possible value for the position
property looks like this:
.example { position: relative; }
So how is this different from a statically positioned element? A relatively positioned element behaves the same way as a static element, except that it is now subject to the values for four other CSS properties. Look at the following example:
.box1 { width: 100px; height: 100px; background: blue; } .box2 { width: 100px; height: 100px; background: green; border: yellow solid; position: relative; top: 20px; left: 20px; } .box3 { width: 100px; height: 100px; background: red; } .box4 { width: 100px; height: 100px; background: pink; }
Assuming these four boxes are the only elements on the page, how will they behave? Well, first they’ll display on the page in the order they appear in the markup, with each box dropping to a new line. But the second box (the green one with the yellow border) will be offset from its original place because of the top
and left
declarations. We could also use the bottom
or right
properties.
So the second box will be offset 20px from the top of its original spot, and 20px from the left of its original spot. You would get a similar effect if you added a top margin of 20px and a left margin of 20px – but with one significant difference: Offsetting the position with top
, left
, bottom
, or right
does not affect the flow of the elements around it. Here’s a screen shot showing how the second box will look, as seen in this demo:
As you can see, positioning an element relatively can cause overlap. And remember that the original space the element occupies is honored, but any offsets will not cause elements around the box to be repositioned.
Absolutely Positioned Elements
Here’s the third value you can use for the position
property:
.example { position: absolute; }
An element set to “position: absolute” is completely removed from the document’s normal flow, and, like “position: relative”, is subject to horizontal and vertical offsets using top
, left
, bottom
, and right
.
But the main difference is the fact that it’s removed from the flow. This means the space originally occupied by the element will not be honored by surrounding elements. Surrounding elements will behave as if the absolutely positioned element is not even there.
Positioning Contexts
When you offset a relatively positioned element, the offsets are relative to the element’s original place in the normal flow. But with an absolutely positioned element, the offsets are relative to the browser viewport, or, to oversimplify it, the whole window, or document body.
But the positioning context of an absolutely positioned element can be changed. This is done by adding “position: relative” to an ancestor element, thus creating a new positioning context. If that sounds confusing, here’s a demonstration.
And here’s a screen shot of the result:
The body element is given a black border, and the “.container” element is given an orange border. This helps show that the green box (set to “position: absolute”) is offset in the context of the relatively positioned “.container” element.
Notice what happens if we remove the “position: relative” declaration from the “.container” element:
Because we’ve removed the explicit positioning context, the green box is now offset in relation to the viewport. And, as mentioned, none of the surrounding elements are affected by the flow of the green box that has been removed from the normal flow.
Fixed Positioned Elements
Here’s the next available option for the position
property:
.example { position: fixed; }
A fixed position element, according to the spec, actually falls under the category of an “absolutely positioned” element. The behaviour of position: fixed
is very similar to an element set to “position: absolute”, with two key differences: First, the positioning context is always the viewport, so the context won’t change by adding “position: relative” to a parent element. Second, fixed position elements will not move when the document is scrolled. Take a look at the screen shot below, taken from the Treehouse blog:
At the top of the page, a promo bar is shown that is fixed on the page, and it stays there even when you scroll. This is done using “position: fixed”. Using fixed positioned elements in combination with z-index, can help you layout and stack elements in unique ways, depending on what you’re trying to accomplish.
New Values in CSS3
The four values I’ve discussed above are the ones that you’ll be using most of the time when employing the position
property. But you should be aware that the CSS3 spec now includes two new values, namely, position: center, and position: page.
I won’t discuss these in detail here, because as far as I know, no browser supports these values. But you can review the spec for details, and if you have any info on browser support, be sure comment.
Present and Future for CSS Positioning
There are lots of articles and blog posts floating around that discuss CSS positioning in more detail. If you plan to support older browsers for some time, then it would be a good idea to understand better these concepts and any related techniques.
But in the future, when features like flexbox, grid layout, and other new layout modules become more universally supported, you might find yourself using positioning much less often.
Thanks you. 🙂
Great piece, thanks for providing links to the references too – W3C draft, etc.
thank you so much
helped me a lot
I always forget the positioning and it always drives me crazy
Waiting for an article about the new values in css3.
thanks!