Absolutely relative HTML elements

From Jimbojw.com

Revision as of 06:40, 22 October 2007; view current revision
←Older revision | Newer revision→
Jump to: navigation, search
Tip: This is part of the Weekly Web Hack article series. If you like it, please subscribe to my blog. Thanks!
{{weeklywebhack}}

In this Weekly Web Hack, I'll demonstrate how to have semantically ordered HTML elements appear visually reordered static width, center floated, single column page...

By the end of this article, you should be able to:

  1. Make a centered single column layout in HTML/CSS (easy to do, and popular for blogs).
  2. Reorder the major elements, putting the most important info first (CSS).

{{itemTags:webhack|html|css}}

For those of you who just can't wait to see a working example:

[http://jimbojw.com/examples/absolutely-relative.html absolutely-relative.html]

== Requirements ==

Here are the requirements for the project:

  1. It must work in all major browsers: IE7, IE6, Firefox, Opera and Safari/Konqueror
  2. The page must appear to have a single static-width column
  3. The column's major elements must appear with the header bar first
  4. The column's html elements must appear in semantic order (header bar after content).

== HTML ==

First, let's lay out the HTML elements as we'd like them to appear. Consider this HTML snippet:


  
The First Box!
The Second Box!

In this case, the globalWrapper represents our single column, and firstBox and secondBox contain our semantically ordered content. The first div contains the relevant page content, while the second div would contain a header of some sort - generally something we'd like to visually display on top of the "first" box.

== CSS ==

First, here is the CSS for the globalWrapper:

  1. globalWrapper {
 width: 500px;
 margin: 4em auto 0 auto;

}

This relatively terse code establishes the following about the globalWrapper:

  • Its width will be 500 pixels (abysmally small for a real site, but good for demonstration).
  • Its top margin should be 4em. This effectively puts a 4em buffer on top of any content.
  • Its left and right margins will be automatically determined to center the div in the middle of the page.
  • Its bottom margin is 0 (not important).

The top margin of 4em is important since this must be tall enough to accommodate the secondBox. Ideally the second box would have a static height - which is usually the case for header bars.

Next, here's the CSS for the firstBox:

  1. firstBox {
 color: white;
 background: red;
 width: 500px;
 padding: 1em;

}

Here we're redefining the 500 pixel width again. This is to account for the 1em padding, which could otherwise muck with the browser's width calculation. If the padding would instead be set to 0, the width attribute could be safely removed.

Finally, this is the CSS for the secondBox:

  1. secondBox {
 color: white;
 background: blue;
 width: 500px;
 padding: 1em;
 position: absolute;
 top: 0;
 left: auto;
 z-index: 0;

}

In this case, we start off with almost exactly the styles for firstBox. However, unlike the other divs in the example which will be placed relative to their parent elements, this box has a position attribute of 'absolute'. The "top:0;" declaration means the div should be placed 0 pixels down from the top of the page, which will put it into globalWrapper's top buffer (or "gutter" as they're sometimes called).

The magic glue that holds this hack together is the "left: auto;" declaration. This tells the browser that the left-hand margin should be calculated in such a way that the div will be positioned in the center of the page.

== Working example ==

The above has been put together and is available for inspection here: [http://jimbojw.com/examples/absolutely-relative.html absolutely-relative.html]

I have tested this locally on Firefox, Opera and Konqueror. Using [http://ipinfo.info/netrenderer/ Geotek's netrenderer] produces good results for IE 6 and 7.

== Improvements, Caveats and Gotchas ==

Of course, as with many hacks, this one needs some use-case specific TLC from any developer that chooses to use it. What follows are a few things to think about during implementation.

  • Obviously since the "width: 500px" declaration is repeated several times in the CSS, it makes sense to move this to a CSS class for ease of maintenance.
  • Different browsers will "center" this stuff somewhat differently, however 'auto' seems to be the same whenever it's calculated. That is, the first and second boxes of the example above will always line up, even if the exact number of pixels indented on the left and right differ from browser-to-browser or version-to-version.
  • If the divs are going to be purely structural (containing other "content" divs), then they probably won't need padding, which eliminates some of the need for absolute width declarations.
  • If padding is used on the inner-divs, it should really be the same for each. Padding can affect width calculations, centering calculations or both.
  • Widths must be specified in pixels or percentages. Specifying a width in em tends to break some 'auto' calculations, notibly in Firefox.
  • It's tempting to specify the widths of the inner div's as 'inherit', however this does not work in either targeted version of Internet Explorer.
  • As mentioned previously, the top margin on the globalWrapper has to be large enough to accomodate the secondBox.

Anyway, I sincerely hope this helps someone out there. Enjoy! As always I'll be happy to answer any questions. ----- Got something to say?

Leave a comment

or, read [[Talk:{{PAGENAME}}|what others have said...]]

__NOEDITSECTION__ __NOTOC__

In this Weekly Web Hack, I'll demonstrate how to have semantically ordered HTML elements appear visually reordered static width, center floated, single column page.

By the end of this article, you should be able to:

  1. Make a centered single column layout in HTML/CSS (easy to do, and popular for blogs).
  2. Reorder the major elements, putting the most important info first (CSS).

For those of you who just can't wait to see a working example:

absolutely-relative.html

Requirements

Here are the requirements for the project:

  1. It must work in all major browsers: IE7, IE6, Firefox, Opera and Safari/Konqueror
  2. The page must appear to have a single static-width column
  3. The column's major elements must appear with the header bar first
  4. The column's html elements must appear in semantic order (header bar after content).

HTML

First, let's lay out the HTML elements as we'd like them to appear. Consider this HTML snippet:

<body>
  <div id="globalWrapper">
    <div id="firstBox"> The First Box! </div>
    <div id="secondBox"> The Second Box! </div>
  </div>
</body>

In this case, the globalWrapper represents our single column, and firstBox and secondBox contain our semantically ordered content. The first div contains the relevant page content, while the second div would contain a header of some sort - generally something we'd like to visually display on top of the "first" box.

CSS

First, here is the CSS for the globalWrapper:

#globalWrapper {
  width: 500px;
  margin: 4em auto 0 auto;
}

This relatively terse code establishes the following about the globalWrapper:

  • Its width will be 500 pixels (abysmally small for a real site, but good for demonstration).
  • Its top margin should be 4em. This effectively puts a 4em buffer on top of any content.
  • Its left and right margins will be automatically determined to center the div in the middle of the page.
  • Its bottom margin is 0 (not important).

The top margin of 4em is important since this must be tall enough to accommodate the secondBox. Ideally the second box would have a static height - which is usually the case for header bars.

Next, here's the CSS for the firstBox:

#firstBox {
  color: white;
  background: red;
  width: 500px;
  padding: 1em;
}

Here we're redefining the 500 pixel width again. This is to account for the 1em padding, which could otherwise muck with the browser's width calculation. If the padding would instead be set to 0, the width attribute could be safely removed.

Finally, this is the CSS for the secondBox:

#secondBox {
  color: white;
  background: blue;
  width: 500px;
  padding: 1em;
  position: absolute;
  top: 0;
  left: auto;
  z-index: 0;
}

In this case, we start off with almost exactly the styles for firstBox. However, unlike the other divs in the example which will be placed relative to their parent elements, this box has a position attribute of 'absolute'. The "top:0;" declaration means the div should be placed 0 pixels down from the top of the page, which will put it into globalWrapper's top buffer (or "gutter" as they're sometimes called).

The magic glue that holds this hack together is the "left: auto;" declaration. This tells the browser that the left-hand margin should be calculated in such a way that the div will be positioned in the center of the page.

Working example

The above has been put together and is available for inspection here: absolutely-relative.html

I have tested this locally on Firefox, Opera and Konqueror. Using Geotek's netrenderer produces good results for IE 6 and 7.

Improvements, Caveats and Gotchas

Of course, as with many hacks, this one needs some use-case specific TLC from any developer that chooses to use it. What follows are a few things to think about during implementation.

  • Obviously since the "width: 500px" declaration is repeated several times in the CSS, it makes sense to move this to a CSS class for ease of maintenance.
  • Different browsers will "center" this stuff somewhat differently, however 'auto' seems to be the same whenever it's calculated. That is, the first and second boxes of the example above will always line up, even if the exact number of pixels indented on the left and right differ from browser-to-browser or version-to-version.
  • If the divs are going to be purely structural (containing other "content" divs), then they probably won't need padding, which eliminates some of the need for absolute width declarations.
  • If padding is used on the inner-divs, it should really be the same for each. Padding can affect width calculations, centering calculations or both.
  • Widths must be specified in pixels or percentages. Specifying a width in em tends to break some 'auto' calculations, notibly in Firefox.
  • It's tempting to specify the widths of the inner div's as 'inherit', however this does not work in either targeted version of Internet Explorer.
  • As mentioned previously, the top margin on the globalWrapper has to be large enough to accomodate the secondBox.

Anyway, I sincerely hope this helps someone out there. Enjoy! As always I'll be happy to answer any questions.


Got something to say?

Leave a comment

Name (required):

Website:

Comment:

or, read what others have said...