The CSS Position Property

By YUI TeamDecember 14th, 2010


About the author:
Thierry Koblentz is a front-end engineer at Yahoo!

He owns
TJK Design,
ez-css.org and
css-101.org. You can follow Thierry on Twitter at
@thierrykoblentz
.

This property applies to all elements. It has five possible values:

  • static
  • relative
  • absolute
  • fixed
  • inherit

position:static

From section 9 Visual formatting model:

The box is a normal box, laid out according to the normal flow. The
top,
right,
bottom,
and left
properties do not apply.

Things to notice in this demo

  • The second box shows exactly where it would be without the position declaration.
  • The value given to top does not apply because in a ‘static’ context, the computed value of box offsets is always auto.

Things to remember

  • If the position property of an element has the value of static, that element is not said to be positioned.
  • Because static is the initial value (the default value), there is no need to include such styling in a declaration block unless it is to overwrite a different value.

position:relative

From section 9 Visual formatting model:

The box’s position is calculated according to the normal flow (this is called the position in normal flow). Then the box is offset relative to its normal position. When a box B is relatively positioned, the position of the following box is calculated as though B were not offset.

Things to notice in this demo

  • Box ‘two’ has moved down by 300 pixels, but box ‘three’ as well as the following paragraphs stayed in place. It appears like if the box was lifted from the page, leaving its footprint behind. This is because offsetting a relatively positioned box does not disturb the flow.
  • The relatively positioned box overlaps the following elements. It shows in front of other boxes.

Things to remember

  • Computed values are always left = -right and top = -bottom. If the direction of the containing block is ltr, the value of ‘left’ wins and ‘right’ becomes -‘left’. If direction of the containing block is rtl, ‘right’ wins and ‘left’ is ignored. Authors could take advantage of how things work by setting equal value to opposite properties.
  • Unlike with the ‘absolute’ model, top, right, bottom, and left properties cannot stretch nor shrink the box (they cannot change its size).

position:absolute

From section 9 Visual formatting model:

The box’s position (and possibly size) is specified with the top, right, bottom, and left properties. These properties specify offsets with respect to the box’s containing block. A absolutely positioned box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block. Also, though absolutely positioned boxes have margins, they do not collapse with any other margins.

Things to notice in this demo

  • Because no box offset is specified, box ‘two’ did not move from its original position, but if we had used top:0;left:0; for example, that box would be at the top left corner of the viewport.
  • Layout wise, it is like box ‘two’ had been styled with display:none. The box has been removed from the flow.
  • With box ‘two’ out of the flow, box ‘three’ has moved up against box ‘one’ (the paragraphs have followed).
  • Like all elements removed from the flow, box ‘two’ has horizontally shrink-wrapped.

Things to remember

  • For any ‘absolute’ or ‘fixed’ positioned element the computed value for display is block.
  • For any ‘absolute’ or ‘fixed’ positioned element the computed value for float is none.
  • A ‘containing block’ is a box that establishes a positioning context. It is established by the nearest ancestor with a ‘position’ of ‘absolute’, ‘relative’ or ‘fixed’. This means the parent box may not be the containing block.
  • The default position of a absolutely positioned box is not always the same as if it was styled with top:0;left:0; (in a LTR context). And this is for two reasons:
    1. The containing block for a positioned box is established by the nearest positioned ancestor; if there is none, the reference container is the root element. The containing block in which the root element lives is a rectangle called the initial containing block. For continuous media, it has the dimensions of the viewport (a window or other viewing area on the screen) and is anchored at the canvas origin. This example shows the box positioned in relation to the viewport (the default containing block).
    2. The element is positioned in reference to the padding box, not the content box nor the border box of the containing block. This new example demonstrates where box ‘two’ would be if the edges of the padding box did not touch the edges of the content box (the containing block being body).
  • The size of the box may be the result of the top, right, bottom, and left property values. For examples, zeroing out all properties will make the box stretch to match the dimensions of the padding box of its containing block. See zeroing out all box offsets (note: ie6 does not stretch the box).
  • To create a mask overlay that does not scroll with the document (as in the previous example), either use fixed instead of absolute or style body with position:relative as the initial positioning block is the viewport (styling html would not work in IE). As this overlay demo shows.
  • position:absolute triggers haslayout.

Most important thing to remember

Because this positioning scheme removes boxes from the flow, it is considered bad pratice to use it for layout.

position:fixed

From section 9 Visual formatting model:

Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport. For continuous media, fixed boxes do not move when the document is scrolled. In this respect, they are similar to fixed background images. For paged media (where the content of the document is split into one or more discrete pages), boxes with fixed positions are repeated on every page. This is useful for placing, for instance, a signature at the bottom of each page. Boxes with fixed position that are larger than the page area are clipped. Parts of the fixed position box that are not visible in the initial containing block will not print.

Things to notice in this demo:

  • Since fixed positioning is a subcategory of absolute positioning, everything that was true for ‘absolute’ is also true for ‘fixed’ (the element shrink-wraps, it is removed from the flow, etc.).
  • The box is positioned in relation to the viewport, it does not scroll with the page.
  • In IE 6, the box appears as a static box, but there is a "funny" workaround for that.
  • When printing the document, box ‘two’ appears on every single page.

Things to remember:

  • The box’s position is calculated according to the ‘absolute’ model, but in addition, the box is fixed with respect to some reference. In the case of handheld, projection, screen, tty, and tv media types, the box is fixed with respect to the viewport and does not move when scrolled.
  • Content may be inaccessile to sighted users if part of the box is outside of the viewport area.
  • In the case of the print media type, authors may want to prevent an element from appearing on each printed page. Maybe using a @media rule, as in:
    @media print { 
      #logo {position: static;}
    }
  • Like position:absolute, position:fixed will trigger haslayout in IE.

position:inherit

If position:inherit is specified for a given box, then it will take the same computed value as the property for the box’s parent.

Note that IE 6 and 7 do not support this keyword except when used with direction and visibility (see the CSS Property Value inherit).

Things to consider

Box offsets

Be aware that for absolutely and fixed positioned boxes, values set in percentage for top, right, bottom, and left are computed according to the dimensions of the containing block (which may not be the parent box).

‘position’ and ‘overflow’

A box styled with overflow:hidden will clip relatively positioned elements (nested boxes), but it will not always hide absolutely positioned ones. This is because the parent box is not always the containing block (the nearest ancestor with a ‘position’ of ‘absolute’, ‘relative’ or ‘fixed’).

In short, this means absolutely positioned elements will show outside of a box styled with overflow:hidden unless their containing block is the box itself or an element inside the said box. This demo page shows how things work.

Margins

Authors can use margins on elements regardless of their positioning scheme.

The case of IE

In IE, ‘positioning’ a box may be a blessing or a curse:

  • In IE6, position:relative (with haslayout) can be used to prevent a box styled with negative margins from being clipped by a parent container (see how positioning the box fixes this issue).
  • Positioning an element may "disturb" the way boxes stack in IE 6 and 7 as this may establish a new stacking context (see a test case).

Stacking order and stacking level

  • According to the sequence in the source code, positioned boxes come in front of floats and boxes in the normal flow.
  • Authors can specify stack levels via the ‘z-index’ property only on positioned boxes.
  • In IE6 and 7, the simple fact of positioning a box can establish a stacking context (see above, "the case of IE").

Mobile devices

Read PPK’s article, the [sixth] position value, to find out why mobile browser vendors cannot really support position:fixed.

Further readings

A "ghost" analogy by
DrLangbhani:

An element with position relative is always offset relative to it’s normal position in the flow. In other words, it is shifted relative to where it would be under normal circumstances, and shifting it doesn’t affect the layout of elements around it. It’s like a ghost that has left its body behind. A body that has width and height and affects its surroundings but is invisible. The ghostly box is able to move but is still connected to the old body in that its position is still measured from it. Now an element with position absolute is even easier. It no longer affects its surroundings at all (it’s pulled out of the layout flow). It’s now a true ghost with no body left behind. As far as its sibling elements are concerned it’s as if it no longer exists. To get its position, look through each of its parent elements until you find one with either position: relative, [position: fixed,] or position: absolute. That element will serve as the reference point. Only if you don’t find a "positioned" element will it be offset from the document.

Tagged as:

6 Comments

  1. Nice post!

    Understanding the difference between absolute and relative positioning seems to be a source of a lot of confusion for folks who haven’t used it much in practice. The ghost analogy helps. I have my own analogy is that position:relative leaves a “footprint” behind, whereas position:absolute doesn’t.

    Incidentally this is also a good interview question.. just in case you have to interview folks as part of your job.

  2. Hi David,

    You’re right. There is a lot of confusion when it comes to the position property. I believe the most frequent mistake people make is to believe containing blocks play a role on the positioning of nested relatively positioned elements.

    Thanks for your feedback!

  3. Hello!
    I’ve found several spelling errors.
    In the “position:absolute” section,the red box,the third line,it’s “An absolute position box”.
    In the last “Things to consider” section,the “the case of IE”,the first term,the second line,it’s “margin”,not “nargin”.
    Yours

  4. Peter Abrahamsen said:
    December 17, 2010 at 9:54 am

    I was surprised not to see any discussion of how the position property works on mobile devices. See this post at Quirksmode:

    http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

  5. @tycable

    Thanks a lot for reporting these typos.

    @Peter

    Good point, I should have mentioned that ‘fixed’ is broken when it comes to mobile devices (as I do for IE6). I’ll add that and include PPK’s link as well.

    As a side note, that should be the sixth position value.

    Thanks for your feedback

  6. Michael Hessling said:
    December 26, 2010 at 6:38 pm

    Thoroughly enjoyed your comments to the A List Apart CSS Positioning 101 article.

    Also glad I read this article first.