Positioning elements

It's easy enough to place HTML elements into a document, and to change how those elements look with CSS. CSS also allows us to determine where on the page an element will appear.

Element display styles

As we've seen, HTML elements belong to one of two categories: block and inline. By default, block elements are positioned one on top of another on the page, in the order the occur in the HTML source. Inline elements also are positioned on the page in the order they occur in the HTML source, but they're placed in the "flow" of the page's text.

<p>Paragraphs are block elements.</p>
<p>Here's another paragraph. <em>The &lt;em&gt; tag</em> is an inline
element.</p>
<p>Another paragraph.</p>

Paragraphs are block elements.

Here's another paragraph. The <em> tag is an inline element.

Another paragraph.

But we can actually change whether an element is rendered as a block or inline using the CSS display attribute. For example:

<p>Paragraphs are block elements.</p>
<p>Here's another paragraph. <em style="display: block;">The &lt;em&gt;
    tag</em> is an inline element, by default.</p>
<p>Another paragraph.</p>

Paragraphs are block elements.

Here's another paragraph. The <em> tag is an inline element, by default.

Another paragraph.

As you can see, by setting the <em> tag's display attribute to block, we caused it to be rendered on a separate line---i.e., as a block element.

"Floating" elements

You may have noticed that, by default, <img> elements are displayed inline, and usually this ends up with an undesirable effect:

<p><img src="riker.jpg">Some days you get the bear,
and some days the bear gets you. Computer, belay that order. and attack the
Romulans. Now we know what they mean by 'advanced' tactical training. I'll be
sure to note that in my log. A surprise party? Mr. Worf, I hate surprise
parties. I would *never* do that to you. I'd like to think that I haven't
changed those things, sir. A lot of things can change in twelve years,
Admiral.</p>

Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans. Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

Usually what we want instead is for the text to "wrap around" the image. We can accomplish this using the CSS float attribute, like so:

<p><img style="float: left;" src="riker.jpg">Some days you get the bear,
and some days the bear gets you. Computer, belay that order. and attack the
Romulans. Now we know what they mean by 'advanced' tactical training. I'll be
sure to note that in my log. A surprise party? Mr. Worf, I hate surprise
parties. I would *never* do that to you. I'd like to think that I haven't
changed those things, sir. A lot of things can change in twelve years,
Admiral.</p>

Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans. Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

Using left "floats" the image to the left; right floats the image to the right (without having to change where the element occurs in the source code!)

<p><img style="float: right;" src="riker.jpg">Some days you get the bear,
and some days the bear gets you. Computer, belay that order. and attack the
Romulans. Now we know what they mean by 'advanced' tactical training. I'll be
sure to note that in my log. A surprise party? Mr. Worf, I hate surprise
parties. I would *never* do that to you. I'd like to think that I haven't
changed those things, sir. A lot of things can change in twelve years,
Admiral.</p>

Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans. Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

You can also float other elements, not just <img> tags. For example, to create a little "sidebar" out of a <div> element:

<p>
<div style="float: right; width: 100px; font-size: 80%; padding: 0.5em;">
<b>Note</b>: Everyone loves Commander Riker.</div>
Some days you get the bear, and some days the bear gets you. Computer, belay
that order. and attack the Romulans. Now we know what they mean by 'advanced'
tactical training. I'll be sure to note that in my log. A surprise party? Mr.
Worf, I hate surprise parties. I would *never* do that to you. I'd like to
think that I haven't changed those things, sir. A lot of things can change in
twelve years, Admiral.</p>

Note: Everyone loves Commander Riker.
Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans. Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

"Clearing" floats

One thing to remember is that float causes not just the text in one element to wrap around the floated element, but all elements. For example, let's use a slightly larger picture of Commander Riker:

<p><img style="float: right;" src="bigriker.jpg">Some days you get
the bear, and some days the bear gets you. Computer, belay that order. and
attack the Romulans.</p>
<p>Now we know what they mean by 'advanced' tactical training. I'll be
sure to note that in my log. A surprise party? Mr. Worf, I hate surprise
parties. I would *never* do that to you. I'd like to think that I haven't
changed those things, sir. A lot of things can change in twelve years,
Admiral.</p>

Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans.

Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

Ack, it's even still floating into the rest of the HTML in this tutorial page! This is awful! Riker is in everything.

The easy way to ensure that floated elements stay in-place is called the clearfix hack. Here's how it works. If you have a floated element that you want to stay inside of a containing element, add the style overflow: auto; to the containing element. For example, to contain our Riker image in the first paragraph tag only:

<p style="overflow: auto;">
<img style="float: right;" src="bigriker.jpg">Some days you get
the bear, and some days the bear gets you. Computer, belay that order. and
attack the Romulans.</p>
<p>Now we know what they mean by 'advanced' tactical training. I'll be
sure to note that in my log. A surprise party? Mr. Worf, I hate surprise
parties. I would *never* do that to you. I'd like to think that I haven't
changed those things, sir. A lot of things can change in twelve years,
Admiral.</p>

Some days you get the bear, and some days the bear gets you. Computer, belay that order. and attack the Romulans.

Now we know what they mean by 'advanced' tactical training. I'll be sure to note that in my log. A surprise party? Mr. Worf, I hate surprise parties. I would never do that to you. I'd like to think that I haven't changed those things, sir. A lot of things can change in twelve years, Admiral.

Using float and margin to build column a column layout

We can use float and margin-left to build a layout that has two columns. The float ensures that the .menu class <div> appears to the left of the following elements. The margin-left on the <div> with class .main ensures that there's space left beneath the .menu div. (Try taking out the margin-left and see what happens!) Finally, overflow: auto in the .container div ensures that the floated .menu doesn't escape the element and cause other elements beneath it to be text-wrapped around it.

I added some borders to the elements below so you can see where the boxes are.

<style type="text/css">
    .container { overflow: auto; } /* clearfix hack */
    .menu { float: left; width: 150px; border: 1px red solid; }
    .main { margin-left: 155px; border: 1px green solid; }
</style>
<div class="container">
    <div class="menu">
        This will appear on the left.
        <ul>
            <li>Stuff</li>
            <li>Things</li>
            <li>More stuff</li>
        </ul>
    </div>
    <div class="main">
        Captain, why are we out here chasing comets? We could cause a diplomatic
        crisis. Take the ship into the Neutral Zone Wait a minute - you've been
        declared dead. You can't give orders around here. I'd like to think that
        I haven't changed those things, sir. Yesterday I did not know how to eat
        gagh. I suggest you drop it, Mr. Data.
        Captain, why are we out here chasing comets? We could cause a diplomatic
        crisis. Take the ship into the Neutral Zone Wait a minute - you've been
        declared dead. You can't give orders around here. I'd like to think that
        I haven't changed those things, sir. Yesterday I did not know how to eat
        gagh. I suggest you drop it, Mr. Data.
        Captain, why are we out here chasing comets? We could cause a diplomatic
        crisis. Take the ship into the Neutral Zone Wait a minute - you've been
        declared dead. You can't give orders around here. I'd like to think that
        I haven't changed those things, sir. Yesterday I did not know how to eat
        gagh. I suggest you drop it, Mr. Data.
    </div>
</div>
Captain, why are we out here chasing comets? We could cause a diplomatic crisis. Take the ship into the Neutral Zone Wait a minute - you've been declared dead. You can't give orders around here. I'd like to think that I haven't changed those things, sir. Yesterday I did not know how to eat gagh. I suggest you drop it, Mr. Data. Captain, why are we out here chasing comets? We could cause a diplomatic crisis. Take the ship into the Neutral Zone Wait a minute - you've been declared dead. You can't give orders around here. I'd like to think that I haven't changed those things, sir. Yesterday I did not know how to eat gagh. I suggest you drop it, Mr. Data. Captain, why are we out here chasing comets? We could cause a diplomatic crisis. Take the ship into the Neutral Zone Wait a minute - you've been declared dead. You can't give orders around here. I'd like to think that I haven't changed those things, sir. Yesterday I did not know how to eat gagh. I suggest you drop it, Mr. Data.

You might need to fiddle with the width and margin-left pixel values to get the columns to line up right. If you change the padding or border widths of either of the elements, you'll have to adjust the width and margin-left values to compensate in order to make sure that everything fits. (The reason that this is so fiddly is that by default the width attribute controls how wide the element is---before you add in the padding, border, and margin. You can override this behavior, though, using the box-sizing CSS attribute---see The Box Model and Box Sizing on Learn Layout for more information.)

Simple grid layouts with inline-block

One common task that web designers often want to accomplish is creating a "grid" of elements on the page---think like a photo gallery or a portfolio site. There are a number of ways to accomplish this with CSS, but the easiest way to use the CSS display: inline-block attribute. Unlike an inline element, an element with display: inline-block can have a width and height, and won't have its contents wrapped over multiple lines. But unlike a block element, an inline-block element doesn't automatically have whitespace inserted before and after it---it gets placed into the flow of layout as though it were text.

Here's a good overview of the differences and similarities among block, inline, and inline-block (and another).

To demonstrate a grid layout with inline-block, let's write some markup. Let's say we want to show a grid of links to different parts of a hypertext story we're writing. We might start out by creating <div> tags for each part.

<div>
    <div>Chapter 1: Bearly there</div>
    <img src="http://placebear.com/120/120">
</div>
<div>
    <div>Chapter 2: More than I can bear</div>
    <img src="http://placebear.com/120/120">
</div>
<div>
    <div>Chapter 3: Bear everybody knows your name</div>
    <img src="http://placebear.com/120/120">
</div>
<div>
    <div>Chapter 4: Bear and Equitable Treatment</div>
    <img src="http://placebear.com/120/120">
</div>
<div>
    <div>Chapter 5: Bear My Soul</div>
    <img src="http://placebear.com/120/120">
</div>
Chapter 1: Bearly there
Chapter 2: More than I can bear
Chapter 3: Bear everybody knows your name
Chapter 4: Bear and Equitable Treatment
Chapter 5: Bear My Soul

Of course, <div> elements are display: block by default, so these elements are all stacked on top of each other. Let's add some classes to these elements and style them with inline-block:

<style type="text/css"> 
    .storylink { display: inline-block; width: 150px; margin: 10px; }
    .linktitle { margin-bottom: 5px; font-style: italic; }
</style>
<div class="storylink">
    <div class="linktitle">Chapter 1: Bearly there</div>
    <img src="http://placebear.com/120/120">
</div>
<div class="storylink">
    <div class="linktitle">Chapter 2: More than I can bear</div>
    <img src="http://placebear.com/120/120">
</div>
<div class="storylink">
    <div class="linktitle">Chapter 3: Bear everybody knows your name</div>
    <img src="http://placebear.com/120/120">
</div>
<div class="storylink">
    <div class="linktitle">Chapter 4: Bear and Equitable Treatment</div>
    <img src="http://placebear.com/120/120">
</div>
<div class="storylink">
    <div class="linktitle">Chapter 5: Bear My Soul</div>
    <img src="http://placebear.com/120/120">
</div>

As you can see, the inline-block elements are all lined up next to each other, and "flow" in their containing element. (If you resize your browser, you'll note that the elements automatically re-flow to accommodate the size of the window---nice!)

Positioning elements with position

Sometimes float and inline-block aren't enough to get the layout you want. For those cases, you can set the position of an element on the screen with pixel-perfect accuracy using the CSS position attribute, in combination with the top, bottom, left, and right attributes.

The position attribute can have one of several values, which we'll discuss below: relative, absolute, and fixed. In each case, you'll specify the position of the element using either top or bottom (to specify the vertical position of the element) and either left or right (to specify the horizontal position of the element).

Relative position

Setting the position attribute to relative allows you to nudge the element from the location it would be normally when the browser lays out the page. Here's an example:

<p>Now is the
<em style="position: relative; top: 5px; left: 5px;">winter</em>
of our discontent.</p>

Now is the winter of our discontent.

Setting the position of the <em> element to relative allows us to set the top and left attributes. The top attribute tells the browser where on the page to render the element: in particular, how far it should be displayed from the its normal vertical position. The left attribute does the same thing, except for the horizontal position.

These values can be negative as well, causing the element to move up or to the left, instead of down or to the right:

<p>Now is the
<em style="position: relative; top: -10px; left: -15px;">winter</em>
of our discontent.</p>

Now is the winter of our discontent.

Note that position: relative without setting a top or a left just leaves the element exactly where it would have been:

<p>Now is the
<em style="position: relative;">winter</em>
of our discontent.</p>

Now is the winter of our discontent.

Absolute position

Absolute positioning allows you to place an element at an arbitrary position inside of its containing element. For example:

<div style="position: relative; border: 1px black solid;">Now is the
<em style="position: absolute; top: -10px; left: -5px;">winter</em>
of our discontent.</div>
Now is the winter of our discontent.

The word winter is displayed ten pixels above and five pixels to the left, not from where it usually would have been rendered, but from the top-left position of the <div> that contains it. (I've included a border around the <div> so you can see the <div>'s dimensions more clearly.)

Note that for absolute to work, the containing element must have some value for position, even if that position is just relative without a top or left.

Note also that---unlike position: relative---absolute doesn't leave a "gap" where the element would normally have been rendered.

You can use position: absolute to create a "collage" effect, positioning <div>s and other elements on the page at arbitrary positions:

<div style="position: relative; height: 320px;">
    <p style="position: absolute; width: 150px; top: 100px; left: 400px;">
        How long can two people talk about nothing?
    </p>
    <p style="position: absolute; width: 150px; top: 10px; left: 50px;">
        As much as I care about you, my first duty is to the ship.
    </p>
    <p style="position: absolute; width: 150px; top: 220px; left: 320px;">
        You're going to be an interesting companion, Mr. Data.
    </p>
    <img src="bigriker.jpg"
        style="position: absolute; width: 150px; top: 95px; left: 150px;">
</div>

How long can two people talk about nothing?

As much as I care about you, my first duty is to the ship.

You're going to be an interesting companion, Mr. Data.

Fixed position

There's one more kind of position: fixed. A fixed position attaches an element to the browser's "viewport"---i.e., the part of the browser window that displays the actual content of the page. You've probably been wondering what was going on with that annoying "Hello!" up in the corner. Well, here's the code that made it:

<style type="text/css">
    .hellofixed {
        position: fixed;
        top: 0px;
        left: 50px;
        width: 100px;
        background-color: black;
        color: white;
        padding: 5px;
    }
</style>
<div class="hellofixed">Hello!</div>
Hello!

Setting the top and left of a position: fixed element describes how far from the upper left-hand corner of the browser's viewport the element should be positioned. This is useful for making things like menus, toolbars, etc.---anything you want the reader to see regardless of where they've scrolled to on the page.

Setting positions with right and bottom

In all of the examples above, we've used top and left to position elements. You can also use bottom and right---these attributes to the same thing as their counterparts, except they say how far from the bottom or right-hand side of the containing element (or the viewport) to place the element.

An example with absolute:

<div style="position: relative; border: 1px black solid;">Now is the
<em style="position: absolute; bottom: -10px; right: 5px;">winter</em>
of our discontent.</div>
Now is the winter of our discontent.

And an example with fixed:

<style type="text/css">
    .goodbyefixed {
        position: fixed;
        bottom: 0px;
        right: 50px;
        width: 100px;
        background-color: black;
        color: white;
        padding: 5px;
    }
</style>
<div class="goodbyefixed">Goodbye!</div>
Goodbye!

Conclusion

Hey wow! Now you have the tools you need to turn your markup into visual delights, casting your elements carelessly to the four winds, letting them float and flow and stick to the edge of the page. Experiment with everything we've talked about above and see what you can do with it! An easy and powerful way to do experiementation is Chrome Developer Tools. Inspect elements and change their CSS! See how they move around the page!

Some further reading: