CSS Positioning 101
Issue № 318

CSS Positioning 101

If you’re a front end developer or a designer who likes to code, CSS-based layouts are at the very core of your work. In what might be a refresher for some, or even an “a-ha!” for others, let’s look at the CSS position property to see how we can use it to create standards-compliant, table-free CSS layouts.

Article Continues Below

CSS positioning is often misunderstood. Sometimes, in a bug-fixing fury, we apply different position values to a given selector until we get one that works. This is a tedious process that can work for a time, but it behooves us to know why specifying something like position: relative can fix your layout bug. My hope is that we can learn the position property’s values and behaviors, and most importantly, how a value can affect your markup.

The CSS specification offers us five position properties: static, relative, absolute, fixed, and inherit. Each property serves a specific purpose. Understanding that purpose is the key to mastering CSS-based layouts.

Get with the flow#section2

First, let’s take a step back to recognize the world we’re working in. Much like our real world, in CSS, we work within boundaries. In CSS, this boundary is called the normal flow. According to the CSS 2.1 spec:

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block boxes participate in a block formatting context. Inline boxes participate in an inline formatting context.

Think of a “box,” as described by the spec as a wooden block—not unlike the ones you played with as a young whippersnapper. Now, think of the normal flow as a law similar to the law of gravity. The normal flow of the document is how your elements stack one on top of each other, from the top down, in the order in which they appear in your markup. You may remember stacking alphabet blocks into giant towers: The normal flow is no different than those wooden blocks bound by the law of gravity. As a child, you had one block on top of another; in your markup, you have one element after another. What you couldn’t do as a child, however, was give those blocks properties that could defy the law of gravity. All of the sudden, CSS seems a lot cooler than those alphabet blocks.

Static and relative—nothing new here#section3

The static and relative position properties behave like your childhood blocks—they stack as you would expect. Note that static is the default position value of an element, should you fail to apply any other value. If you have three statically positioned elements in your code, they will stack one on top of the next, as you might expect. Let’s take a look at an example with three elements, all with a position value of static:

#box_1 { 
	position: static;
	width: 200px;
	height: 200px;
	background: #ee3e64;
}

#box_2 { 
	position: static;
	width: 200px;
	height: 200px;
	background: #44accf;
}

#box_3 { 
	position: static;
	width: 200px;
	height: 200px;
	background: #b7d84b;
}

In example A, you can see three elements stacked like a simple tower. Fascinating, isn’t it? This is block building 101. Congratulations!

You can use the static value for simple, single-column layouts where each element must sit on top of the next one. If you want to start shifting those elements around using offset properties such as top, right, bottom, and left, you’re out of luck. These properties are unavailable to a static element. In fact, a static element can’t even create a new coordinate system for child elements. Wait. What? You lost me at coordinate system. Roger that, Roger. Let’s explain using the relative value.

Relatively positioned elements behave just like statically positioned elements; they play well with others, stack nicely, and don’t cause a ruckus. Hard to believe, right? Take a look at our previous example. This time, we’ve applied the relative value:

#box_1 { 
	position: relative;
	width: 200px;
	height: 200px;
	background: #ee3e64;
}

#box_2 { 
	position: relative;
	width: 200px;
	height: 200px;
	background: #44accf;
}

#box_3 { 
	position: relative;
	width: 200px;
	height: 200px;
	background: #b7d84b;
}

Example B proves that relatively positioned elements behave exactly the same way as statically positioned elements. What you may not know is that elements with a relative position value are like Clark Kent—they hide far greater powers than their static siblings.

For starters, we can adjust a relatively positioned element with offset properties: top, right, bottom, and left. Using the markup from our previous example, let’s add an offset position to #box_2:

#box_2 { 
	position: relative;
	left: 200px;
	width: 200px;
	height: 200px;
	background: #44accf;
}

Example C shows this relative positioning in action. Our three blocks are stacked up nicely, but this time the blue block (#box_2) is pushed out 200 pixels from the left. This is where we start to bend the law of gravity to our will. The blue block is still in the flow of the document—elements are stacking one on top of the other—but notice the green block (#box_3) on the bottom. It’s sitting underneath the blue block, even though the blue block isn’t directly above it. When you use the offset property to shift a relatively positioned element, it doesn’t affect the element(s) that follow. The green box is still positioned as if the blue box were in its non-offset position. Try that with your alphabet block tower.

Creating a coordinate system for child elements is another one of the relative positioning property’s super powers. A coordinate system is a reference point for offset properties. Recall in example C, our blue block (#box_2) is not sitting inside of any other elements, so the coordinate system it’s using to offset itself 200 pixels from the left is the document itself. If we place the #box_2 element inside of #box_1, we’ll get a different result, as #box_2 will position itself relative to the coordinate system from #box_1. For the next example, we won’t change any CSS, we’ll adjust our HTML to move #box_2 inside of #box_1:

<div id="box_1">
	<div id="box_2"></div>
</div>

Example D shows our new markup. Because of the new coordinate system, the blue block measures its offset 200 pixels from the left of the red block (#box_1) instead of the document. This practice is more common with elements set to position: absolute—the way you wish you could have built towers when you were younger.

Absolute—anywhere, anytime#section4

If the relative value acts like Superman, then the absolute value mirrors Inception—a place where you design your own world. Unlike the static and relative values, an absolutely positioned element is removed from the normal flow. This means you can put it anywhere, and it won’t affect or be affected by any other element in the flow. Think of it as an element with a giant strip of velcro on its back. Just tell it where to stick and it sticks. Exactly like the relative value, absolutely positioned elements respond to offset properties for positioning. You can set an element to top: 100px and left: 200px; and that element will sit exactly 100px from the top and 200px from the left of the document. Let’s look at an example using four elements:

#box_1 { 
	position: absolute;
	top: 0;
	left: 0;
	width: 200px;
	height: 200px;
	background: #ee3e64;
}
#box_2 { 
	position: absolute;
	top: 0;
	right: 0;
	width: 200px;
	height: 200px;
	background: #44accf;
}
#box_3 { 
	position: absolute;
	bottom: 0;
	left: 0;
	width: 200px;
	height: 200px;
	background: #b7d84b;
}
#box_4 { 
	position: absolute;
	bottom: 0;
	right: 0;
	width: 200px;
	height: 200px;
	background: #ebde52;
}

Example E shows four boxes, each in a corner of the browser window. Since we set each box’s position value to absolute, we’ve essentially velcroed a box to each corner of our browser window. As you resize the browser, those boxes will stay in their respective corners. If you shrink the browser window so that the boxes overlap, you’ll notice that there is no interaction at all—that’s because they’re out of the document’s normal flow.

Just like relative elements, absolute elements create a new coordinate system for child elements. Example F extends Example E, with an orange element set inside each box. Notice the offset coordinates are in respect to each parent element.

Not to be outdone by other position property values, the absolute value offers some really cool functionality using the offset property. Use two or all four offset properties, and you can stretch an element without defining any width or height—it’s bound only by its parent element or the document itself. Let’s see it in action. Consider the following code:

#box_a { 
	position: absolute; 
	top: 10px;
	right: 10px;
	bottom: 10px;
	left: 10px; 
	background: red; 
}
#box_b { 
	position: absolute; 
	top: 20px;
	right: 20px; 
	bottom: 20px; 
	left: 20px; 
	background: white;
}

In example G we’ve created a border offset 10 pixels by the document, and it’s entirely fluid as the document resize—all with absolute positioning and offsets. In another example, we can create a two-column layout that fills the entire height of the document. Here is the CSS:

#box_1 { 
	position: absolute;
	top: 0;
	right: 20%; 
	bottom: 0;
	left: 0;
	background: #ee3e64;
}

#box_2 { 
	position: absolute; 
	top: 0; 
	right: 0; 
	bottom: 0; 
	left: 80%; 
	background: #b7d84b;
}

Example H shows a full-screen, two-column layout. While this likely isn’t the best approach to a two-column layout, it still shows the power the absolute value holds. Using some creative thinking you can find several useful applications for position: absolute. Similar tricks use only a single offset value. For example:

#box_1 { 
	width: 200px;
	height: 200px;
	background: #ee3e64;
}
#box_2 { 
	position: absolute;
	left: 100px;
	width: 200px;
	height: 200px;
	background: #44accf;
}

In example H2, focus on the blue block (#box_2). Notice how I use only one offset, left: 100px;. This allows the #box_2 element to maintain its top edge and still shift 100 pixels to the left. If we applied a second offset to the top, we would see that our blue block (#box_2) is pulled to the top of the document. See that here, in example H3:

#box_2 { 
	position: absolute;
	top: 0;
	left: 100px;
	width: 200px;
	height: 200px;
	background: #44accf;
}

Fixed—always there#section5

An element with position: fixed shares all the rules of an absolutely positioned element, except that the viewport (browser/device window) positions the fixed element, as opposed to any parent element. Additionally, a fixed element does not scroll with the document. It stays, well…fixed. Let’s look at an example:

#box_2 {
	position: fixed; 
	bottom: 0; 
	left: 0; 
	right: 0; 
}

Example I shows a footer with some copyright text in it as a fixed element. As you scroll, notice that it doesn’t move. Notice that the left and right offset properties are set to zero. Since the fixed value behaves similar to the absolute value, we can stretch the width of the element to fit the viewport while fixing the element to the bottom using bottom: 0;. Use caution with the fixed value: Support in older browsers is spotty at best. For example, older versions of Internet Explorer render fixed elements as static elements. And, you now know that static elements don’t behave like fixed elements, right? If you do plan to use fixed elements in a layout, there are several solutions that can help make your element behave properly in browsers that don’t support the fixed value.

Inherit—Something for nothing#section6

As I mentioned at the beginning of this article, there are five values available to the position property. The fifth value is inherit. It works as the name implies: The element inherits the value of its parent element. Typically, position property elements do not naturally inherit their parent’s values—the static value is assigned if no position value is given. Ultimately, you can type inherit or the parent element’s value and get the same result.

In action#section7

All this talk and no action. Let’s take a look at a real-world example website that uses all the position values. Example J shows a typical website layout with a header, navigation, content, and footer. Let’s walk through each element, discuss its position property, and why we chose that property.

Let’s start with our #container element. This is simply the containing element that I’m using to center our content within the viewport. The #nav element is the first element within our #container element. No position property is assigned to the #nav element, so by default, it’s set to static. This is fine: We don’t need to do anything to offset this element, or create any new coordinate systems with it. We will need to do that with #content on our next element, so for that element, we’ve applied a position property of relative.

Since we’re not using any offsets here, the position value has no real influence on the #content element, but we placed it there to create a new coordinate system for the #callout element. Our #callout element is set to position: absolute, and since its parent element, #content is set to relative, the offset properties we’re using on #callout are based off the coordinates created by #content. The #callout element uses a negative 80px pixel offset on the right to pull the element outside of its containing parent element. Additionally, I’ve used one of the cooler features of the absolute value on our #callout element: by setting the top and bottom offsets to 100px, I’ve stretched the #callout element to the full height of the document minus the 100px offset on top and bottom.

Since the #callout element has an absolute value, it does not affect other elements. Therefore, we need to add some padding to the #content element to keep our paragraphs from disappearing beneath it. Setting the padding on the right of #content to 250px keeps our content in full view for our users. To bring up the rear, we’ve added a footer with a fixed position to keep it fixed to the bottom of the page. As we scroll, our footer stays in place. Just as we added padding to the #content to keep our paragraphs from disappearing under it, we need to do the same for the #footer element as it is a sibling of the absolute value. Adding 60px to the #content element’s bottom padding ensures that we can scroll the entire document and not miss any text that would normally be hidden under the #footer element.

Now we have a nice, simple layout with navigation, some content, a callout area, and a footer using static, relative, absolute, and fixed elements. Since we’re using the fixed value in this layout, we should apply some techniques to make sure that older browsers still respect our design. [Note: There used to be a link to sample techniques, but that site has since been taken over by malware. Apologies. —Ed.]

Conclusion#section8

With the position property’s power, you can accomplish many a layout with confidence and success. Thankfully, 80% of the position property values have excellent support in both modern and older browsers. The fixed value is the one that you should watch out for. Understanding the core of these property values gives you a solid CSS-based layout foundation, limited only by your imagination. Hopefully, your days of guessing position values in a last-minute bug fix frenzy are now over.

About the Author

Noah Stokes

Noah Stokes is a designer and developer with more than a decades' worth of client and product experience. He lives on the Central Coast of California with his wife and three sons. You can find Noah on Twitter at (@motherfuton) or on his website noahstokes.com.

66 Reader Comments

  1. I can’t really believe how much I didn’t understand and had forgotten about css positioning… It’s a bit depressing to be honest. I’ve probably taken it for granted because everything I’ve done has been on-the-go and I haven’t really needed to learn all of the theory behind stuff like css positioning.

    Thanks for the awesome article and I really like your website, despite it’s simplicity.

  2. I never realised quite how redundant the CSS spec is. The final two lines of this selection are almost insultingly pointless and unhelpful.

    “Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block boxes participate in a block formatting context. Inline boxes participate in an inline formatting context.”

  3. Thanks for this well written article. It really helps describe the elements. However, I believe the code listed for example H is incorrect. It doesn’t match the code on the sample page.

    Thanks again.

  4. Nice summary with demonstrative examples.

    A remark to one thing you’ll find zillion times: In example J, the ‘#container’ element (which is the only child of ‘body’) is not needed. With ‘html’ and ‘body’, there are already two containers waiting to get styled.

    Just apply the rules for ‘body’ to ‘html’ and the rules for ‘#container’ to ‘body’ and you’re done without this ‘div’.

  5. even though the rest of the article seems pretty basic:
    using position:absolute together with values for all 4 sides to stretch an element relative to it’s container is the best css trickery i’ve seen for a long time. thanks for this.

  6. This came just a little too late for me, but brilliant anyway.

    I’m a developer rather than a designer, but about once every 3 months I find myself having to create a new CSS layout for a website. My old technique was always the trial-and-error “let’s try position: relative and see what effect that has”, but the last time I had to do it (having read various things) I discovered that suddenly I understood _why_ position: relative affected child elements, and what the absolute offsets were absolute in relation to.

    If only I’d read this a year or two ago, I don’t think I would’ve had to go through all that trial-and-error pain 🙂

  7. Unlike skilldrick above, this article is dead on with its timing. Just what I needed for a site I’m currently working on! All the examples are easy to follow and understand, and don’t require lots of weird CSS twistiness to achieve results. Thanks!

  8. Thanks for the great article on positioning. This is a topic that really needs to be understood by anyone hoping to design top-notch websites.

  9. @Dennis B – You are correct, I’ll see if we can’t get that corrected.

    @Gunnar Bittersmann – Thanks for the feedback. My intention with using the #container element was just to center the content on the page. Using the body or html element would have been good options as well.

    @All – Thanks so much for the feedback!

  10. ??With the position property’s power, you can accomplish many a layout with confidence and success??

    Imho, using position absolute to create layouts goes against best practice since it removes elements from the flow which creates issues depending on content and user settings.

    For example, the “last demo”:http://www.alistapart.com/d/css-positioning-101/example_j.html shows that adding content to the “callout” container breaks the whole page.

    As a side note, position *relative* triggers a new stacking context in IE6 which creates another type of problem.

  11. @Theierry Koblentz – Thanks for your feedback. I do believe that there are several valid use cases for the absolute value that don’t cause any issues with regards to layout. Building an entire layout using absolute, as you suggest, wouldn’t be a smart idea and I wasn’t making a case for that. Adding content to the #callout element does cause it to overflow, however this example wasn’t used as a bulletproof layout suggestion, but merely an example of the power of the position property.

  12. To take something that can be so confusing and make it elementary. Good job!

    @Thierry, are you referring to accessibility concerns? Isn’t that what properly structured HTML is for?

  13. @Noah

    ??I do believe that there are several valid use cases for the absolute value that don’t cause any issues with regards to layout??

    When it comes to build layouts I’m afraid there is none. But I’d like to be wrong.
    Let me know if you come up with a demo that is robust enough to allow various content, suports text-resizing, etc.

    One may “cheat” using EMs values to reduce some of the issues, but it’s still a very limited solution.

    @estaples who said: ??are you referring to accessibility concerns???

    accessibility and usability. Containers hide content, content overflows on backgrounds that match text color (as the last example in this article shows), etc.
    Plus, authors trying to implement layouts based on “position” could serve empty containers in IE6 (for the reason I explain in my previous post).

    I guess there is a reason why CSS frameworks out there do not rely on the *position* property to create layouts…

  14. Good article, but I just wanted to point out a bit of confusion in the article vs the example.

    Example G doesn’t match the articles sources code.

    First, the article uses the ID hooks “box_a” / “box_b” while the example uses “box_1” / “box_2”. No big deal.

    But the article shows background colors for White and Red, while the example uses an orange and blue color. This can be more confusing.

    Just thought I’d point that out for consistency. =)

  15. Sorry, I confused myself in the above post.

    The source code I referenced appears to not actually have an example page, while the linked page under that source code is actually for the following articles source code.

    Confused? Me too.

    The previous article source code samples had an example page link that immediately followed the code. At “Example G”, that link is for the up-coming code sample, while the immediately previous code sample is not related.

    That got a little confusing as I was expected it to continue the same format of “Source Code / Example Link”.

  16. Thanx for the wonderfull article. I believe many of us need to be reminded from time to time to keep in touch with the basics instead of just using what we’ve always done, just because we’ve always done it that way.

    But I’m sorry to say that the “Fixed” value isn’t as fixed as the specifications say. For instance, on Safari on an iPad I noticed that the “#box2” just scrolls. And on the standard Android browser the “#box2” doesn’t only scroll but sometimes it jumps up and sticks.

    This is something you need to keep in the back of your mind if you use the “fixed” value. Fixed isnt always fixed.

  17. @johnboxall – I thought about that, but those colors just weren’t as pretty 😀

    @John Bertucci – Good catch, you are correct in that there are a few inconsistencies. We’ll get those cleaned up ASAP, thanks!

  18. bq. When it comes to build layouts I’m afraid there is none. But I’d like to be wrong. Let me know if you come up with a demo that is robust enough to allow various content, suports text-resizing, etc.

    Absolute position, especially in concert with min-height and min-width is great for dealing with replaced elements that cannot scale—e.g. images and videos while still allowing the content area to stretch based on its containing block, e.g. “this gist”:https://gist.github.com/702419 .

  19. I think your description of relatively position elements (examples C & D) is a bit misleading. If I set *left: 200px* on a relatively positioned element then it will be offset 200px from its *normal position* in the flow, not to the document (if it has no positioned parent) or parent element (if there is positioned parent) as suggested in the examples. Any parent coordinate system has no effect on a relatively positioned element, since it acts as its own coordinate system.

  20. @Ryan Cannon

    ??Absolute position, especially in concert with min-height and min-width is great for dealing with replaced elements that cannot scale—e.g. images and videos while still allowing the content area to stretch based on its containing block??

    That gist does not have much to do with page layout, right? The only thing it saves you from is using a wrapper to keep the images in their own rail. Less markup may be, but much less robust as the styling is bound to the image width.

    As a side note, images *can* scale as they have an intrinsic ratio. And videos can too with the help of position:absolute + padding, check this “article on A List Apart”:http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/

  21. i have been using the “trial and error” method for setting those positions… but have been going through some nice tutorials too . Though not crystal clear yet i have been able to save lot of time going through them .This one too has helped me to get closer to “position”.

  22. Great article, but I think you should also mention about z-indexing. As it seems quite ovious, that you can z-indexing elements with position absolute, it’s not so obvious, that you can also z-index elements with position relative. 🙂

  23. @Thierry Koblentz @Ryan Cannon – Good discussion, but something that is beyond the scope of this intro article. This just reminds me of how great CSS positioning is, there are a multitude of ways to layout a site.

    @nd_macias – You bring up a good point with z-index. I opted to leave it out of this article in an attempt to focus on the very basics of positioning.

  24. A great tutorial, and clearly shows why tables are not always needed.

    But remember that tables are still the best way to show tabular data in order to retain semantic/meaningful relationships. If you don’t care about this, remember that those who use screen readers (including search engines) depend on table headers to help scan data. And, of course, with CSS you can “pretty up” your table all you want 🙂

  25. Good article!

    I just want to point out a mistake in your code for the Example H. It seems you’ve copy-pasted Top, Right, Bottom & Left margins from Example G and forgot to modify the values for Example H.

    I sent you a message over at Twitter regarding this but thinking you might be busy, I’m leaving this comment.

    You should fix the example as soon as possible because being an article for beginners, it will leave them badly confused.

  26. @avinash Thanks for your feedback via Twitter. I’ve submitted the fix to the ALA team and expect an update soon.

    @lily Very good question! While I don’t know the answer off the top of my head and without doing the necessary research, I will say that I do not think there is any performance hit on the browser when rendering a page with one position value vs. another.

  27. im a bit confused. Im a student in college trying to figure this out.
    when i write top: 20px its moving FROM the top 20px. not TO the top. is this always true?

    also relative positioning allows me to move something relative to the parent. so moving it over 20px would move it over 20px from the parent rather than document.

    but it seems from your article, absolute also moves from the parent element (if the parent element isnt static) but doesnt interrupt the flow of the rest of the page while relative does?

    with relative positioning, whats the point in using a float?

  28. ??also relative positioning allows me to move something relative to the parent??

    No, this is what the article says, but it is not true. The offset is in relation to the position of the element itself (in the normal flow). In other words, top:20px is 20px away from its original position. It has *nothing* to do with its parent nor with the document.

  29. @shamyugy4 – bq. also relative positioning allows me to move something relative to the parent
    Yes, in that the coordinate system it is referencing is starting at the top left of it’s parent element, if that element is set to relative.

    @Theirry Koblentz – As long as the parent element is set to relative or absolute, it will serve as a new coordinate system.

  30. ??As long as the parent element is set to relative or absolute, it will serve as a new coordinate system??

    This is *not true* and you are confusing people with your article and comments. Please do the appropriate edits.

    This is what the spec [1] says about the relative positioning scheme:
    “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”.

    What you call a ??a new coordinate system?? is in fact called the box’s *containing block*. But this is related to the *absolute* positioning scheme (not the relative one).

    [1] “Section 9 Visual formatting model”:http://www.w3.org/TR/CSS2/visuren.html#choose-position

  31. Ah, nothing like a good old css debate. @ ThieryyKoblentz, without looking too much like the little guy peering out from behind you waving my fist, you’re absolutely right (although I can claim prior art, having mentioned this in post 20).

    Explaining the mechanics of absolute and relative positioning in css has always felt like a challange, but I’ll give it a go.

    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, 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.

    Long winded, and easier with diagrams I’m sure. I may not have made it any easier to understand, but the article certainly has it wrong. I agree with @ThieryyKoblentz that it could cause more confusion than it cures.

  32. This article was just what I needed. As a Flash Developer making the transition to web standards, positioning is by far one of the most frustrating techniques to master.

  33. @Thierry Koblentz – I appreciate the follow up and passion that you are bringing to this discussion. Where you say:

    The offset is in relation to the position of the element itself (in the normal flow). In other words, top:20px is 20px away from its original position. It has nothing to do with its parent nor with the document.

    You are correct and I don’t believe that I’m contradicting you in this article. What I’m trying to get at by referencing the parent element is for example:

    If a parent element is sitting in the middle of the page and a child element is offset from that, then it will be offset from the middle of the page since it’s parent is sitting there.

    Yes, it is it’s original position as you state above, I was emphasizing the parent as a way to say if the parent is in a particular place on the page, relatively or absolutely positioned, you can position off of that placed element with a child element. I hope that makes sense. I do believe that we are getting at the same thing here.

    @DrLangbhani – I really enjoyed your “ghost” analogy – that’s a great example. Hopefully my reply above to Thierry makes sense to you as well.

    @beninteractive – I’m glad that it could get you a few steps closer to mastering!

  34. I found this article refreshing. Since the advent of WP and all the themes and frameworks, there hasn’t been a whole lot of full layout CSS going on.

    I do a fair amount of Custom CSS using a Thesis Theme but it’s mostly for tweaking, placement, etc.

    I [sort of] miss the days of really using all these positioning elements. But not really.

    🙂

  35. It might be considered basic, but we can all stand to be reminded of the basics from time-to-time. The article was well written as expected—I’ll be sure to pass this on for reference material and credit ALA.

    Again, terrific post—thanks!

  36. What is the point of relative positioning if you can’t have any content inside of your relatively positioned divs?

    If you try to put any content inside Example D, it will look something like this, when we would realy want something like this which was obtained with absolute positioning.

    Maybe I’m looking at this from the wrong angle, but I couldn’t for the sake of hell position my content properly in relative divs.

    Anyone have any ideas?

  37. @paulici12 – In your test.html, using the absolute value removed the elements from the document flow which is why they move around exactly as you would like. In test2.html the relative value still keeps the elements in the document flow. This means that because the id=”box_2″ comes after the text in id=”box_1″ it will position itself after the text; thinking back to the stacking of blocks analogy, id=”box_2″ is being stacked underneath the text.

  38. Thank you for posting this article! I come across a useful article on CSS positioning about once a month and always read them since–as you pointed out–positioning is so important and still fairly misunderstood by novice and advanced CSS coders alike.

    This article takes a much simpler and coherent approach to positioning than most others that I’ve read.

  39. Very good overview of this topic, as one in the crowd “technical developer that occasionally has to do some css work” this was perfect!

    I fond one other difference between absolute and relative. I made a form, using width: on the labels to position the form fields correctly. Worked fine until I came to the first set of radio buttons (separated with a br/) Then the upper one was correctly placed, whereas the lower one lined up with the label. Wrapping those into a div with position:relative made no difference, whereas position:absolute made the radiobuttons align just as I wanted them to, whereas the relative box was allowed to be “squeezed between the lines”.

  40. I never fully understood positioning elements, that is until now. This was a very well written article and I thank you for saving me much of the frustration I would have gone through had I not found and read this piece. Keep up the great work.

  41. Brilliant post and elegantly explained. Your post is as elegant as the CSS which is laid out. Thanks for the example pages as well. It helps draw a better picture and makes things easier to understand. I’ll be giving this post the social media treatment.

    Thank you

  42. I really enjoyed this article. It was a nice refresher to some CSS of which I’m a little rusty with. The examples were really helpful.

  43. I needed this article! Thank you.
    On the last example, the footer does not stay fixed on my iPhone 4.

  44. 1. There is an accessibility issue with the use of absolute or fixed positioning for text blocks. This often results in text being cut off or text overprinting other text if the site visitor has set a larger font size than the site designer expects.

    2. There is a usability issue with the use of fixed positioning. If the site visitor scrolls by clicking just above the down arrow on the scroll bar, at least Firefox 3.6 Windows, and possibly other user agents, does not take the height of fixed elements into account when deciding how far to scroll. This often results in one or two lines of text being missed, that is, not displayed to the site visitor before or after scrolling. So the site visitor has to train themselves not to use that scrolling method on such a site.

  45. 2. Actually, two scrolling methods may be taken away by a fixed block.

    For the example http://www.alistapart.com/d/css-positioning-101/example_j.html in a browser sized at approximately 1124 x 563 and the default font size:

    The last line of text shown is in the second paragraph:

    bq. nec dolor augue, sit amet blandit urna. Curabitur vitae elit id sem blandit tincidunt. Fusce aliquam sodales mauris

    Scrolling by clicking just above the arrow makes the new top line:

    bq. libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Lorem ipsum dolor

    with a sliver cut off from the top, missing the line:

    bq. vitae molestie. Aenean sit amet ligula sapien. Donec luctus ultrices condimentum. Fusce ac velit odio, sed luctus

    Scrolling by pressing the space bar did not lose any text at the default font size, but at 18-point minimum font size, the last line before scrolling is in the first paragraph:

    bq. tristique condimentum, odio justo faucibus diam, sed imperdiet

    Pressing the space bar makes the new top line as:

    bq. rutrum ut sem. Maecenas pulvinar bibendum lectus vel malesuada.

    meaning the line:

    bq. metus dui non augue. Ut felis enim, accumsan id tempor vitae

    was skipped. Usability and accessibily issue.

  46. It was a pleasure to read this article about necessary basics for css-layouts and remembering the old days building creative constructions with wooden blocks. And you are right: With css bulding is even cooler! I’ve translated this article into German: http://kleines-universum.de/html-css/css-position-einmaleins-aus-alistapart/
    I’ve a question also for future translations: Is it okay to deeplink the given examples or should I copy them to my webspace? Thank you very much!

  47. I find positioning extremely frustrating especially if im working on a new design, when you test in the browser, Firefox, Chrome and I.E can be quite different especially if you want pixel perfect positioning. Usually I make a div container and place everything in it get it to work in as many of the browsers as I can and then use a hack for the one I cant. Which ultimately isn’t the best solution but works for the minute.

  48. “we apply different position values to a given selector until we get one that works” – well, actually we do this because there are browsers out there that don’t respect standards. Ten years ago we’ve learned that all CSS is try and error – and we still need to come over it.
    As long as browsers don’t implement CSS like it’s written in the specs, theres less reason to study the specs, exactly?

  49. Just a “thank you” from this self-taught artist-designer. I’ve learned this material a number of times when things didn’t fall together as I expected on the page. I think that now, thanks to your articulate explanation, I’ve finally got a handle on it for good. It’s not rocket science, but until you understand the underlying logic, it makes no intuitive sense. Now I think I do. Thanks for taking the time to lay it out clearly. Numerous books have essentially the same information, but have somehow still left me a little lost. Shows how important good writing is. It’s a lot more than efficient “content delivery.”

  50. indeed with css we will save more energy when the page loads, I like this trick and if it had been added image maybe we can add background: # color url(image link) to add texture, and there will be more fantastic

  51. This is very well written article, good to have basics revised again. But this code could have been more optimised. That is what I think..

  52. Thanks for the clear instructions. I am fairly new to css and this explained a concept that has had me tearing my hair out. Straight away I was able to use what I learned to solve a problem on my site, in 5 minutes, that had, had me going around in circles for about 2 hours. Thanks.

  53. @ UKdynamo – Thanks for the feedback! Indeed the code could have been optimized, but for the sake of explanation and simplicity in learning it is presented as is.

  54. Thanks so much for the clearly written and illustrated article. This is exactly what I’ve been searching for in a positioning tutorial.

  55. I’d been looking for a source to explain the basics of CSS Positioning. I am new to web design and really appreciated this well-worded article with great examples. Thanks!

  56. The article doesn’t really establish how contexts work for relative positioning. Example D nests the “blue” box* inside the red one, and that appears to be how you make the blue box display to the right of the red box and at the same level.

    What you don’t establish is how to make two boxes appear on the same horizontal level — have the same “top” offset — without one being nested inside the other.

    If that’s not possible, it would be a good thing to tell us so, so we don’t waste hours trying to figure out how to make this fairly obvious-seeming thing work. If it _is_ possible, you would do well to construct your example to illustrate as much — since it’s clearly a preferable use-case to nesting a box inside another box to give the illusion of them having the same “top” offset.


    *It would be helpful if you used more obvious hex triplets to create your “red”, “blue”, and “green” examples — using the ones you do is basically a way of saying to users “you’re not advanced enough to play in our club, come back when you learn to read hex.”

  57. … the relative positioning use-case in this article is completely unrealistic.

  58. For example H2, “This allows the #box_2 element to maintain its top edge and still shift 100 pixels to the left.” should be “This allows the #box_2 element to maintain its top edge and still shift 100 pixels to the right.”

  59. Thank you so much for writing this article. It has definitely taken the “mystery” and guess work out of positioning.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA