Jump Menu : Content | Explore | Comments | Search | Home | Sitemap | Contact | Login | Access.

Absolute Horizontal and Vertical Centering via CSS

Recently, a reader named Max encountered some scrolling issues while implementing our absolutely centered layout technique. Of course, by “absolutely centered” we are referring to content that remains positioned dead-center regardless of how the browser is resized. After noticing the scrollbar deficiency, Max kindly dropped a comment to explain the issue:

[…] the div solution works well, only one problem maybe somebody can help:
if you make the browser window smaller then the div is -> the scrollbar doenst fit right und you cant scroll over the whole area …

Apparently, because the horizontal/vertical centering method outlined in our original article employs absolute positioning with negative margins, resizing the browser to be smaller than the centered division results in cropped content that is inaccessible via scrollbar. Although this is the first I have heard about this issue, I went ahead and examined the alternate centering technique via the link generously shared by Max.

As it turns out, the proposed solution to the broken-scrollbar problem takes an entirely different approach to the absolute centering of a division (div). Rather than using an absolutely centered wrapper div to align the content, this alternate approach employs a floated “distance” div to set the relative height, and then floats the “content” div relative to the distance div. Sound confusing? Let’s check out the core functionality behind the technique..

First, throw down this (X)HTML markup:

<body>

   <div id="distance"></div>
   <div id="content">
      <!-- absolutely centered content -->
   </div>

</body>

Then, apply the following (heavily commented) CSS:

html, body {
	height: 100%;         /* required */
}
body {
	text-align: center;   /* horizontal centering hack for IE */
	padding: 0;           /* required to "hide" distance div */
	margin: 0;            /* required to "hide" distance div */
}
div#distance { 
	margin-bottom: -10em; /* half of content height */
	background: red;      /* temporary - used to see div */
	width: 1px;           /* required to "hide" distance div */
	height: 50%;          /* required */
	float: left;          /* required */

}
div#content {
	position: relative;   /* positions content on top of distance */
	text-align: left;     /* horizontal centering hack for IE */
	height: 20em;         /* required - desired height */
	width: 40em;          /* required - desired width */
	background: blue;     /* cosmetic */
	margin: 0 auto;       /* required */
	clear: left;          /* required */
}

Finally, if you are concerned about supporting the now-archaic Internet Explorer for Mac, use the following hack:

<style type="text/css">@import("ie5mac-only.css");</style>

..to import a stylesheet with this rule (required only by IE5 for Mac):

html, body {
	height: auto;   /* required only for IE5 mac */
}

Examining this code, we first notice the straightforward (X)HTML markup. As with our original method, only two divisions are required to make it work. Looking at the heavily commented CSS code, the trick behind this technique becomes clear.

After setting the document height to 100%, we invoke the ancient powers of the IE centering hack to center the “content” division horizontally. No surprises there. Then, the ol’ vertical magic happens thanks to the “distance” div, which is set at 50% height and floated left with a width of 1px. Finally, positioned relative to the distance div, the content div copmpletes the IE centering hack and establishes the final width and height of the absolutely centered division.

If I did my job, everything you need to implement this technique is explained via the comments in the code. Note that the last two blocks of code apply only to IE5 Mac, so feel free to exclude it if you could care less about such antiquity 1. And finally, to get a better idea of what exactly is happening with this method, try removing the padding and margin from the body selector and check the results.

Overall, this seems like a solid absolute-centering technique that would be somewhat easier to implement (less math) than our original version. Especially if you are experiencing the same scrollbar issues as Max, I would definitely give this method a try. According to the original author, this technique works in just about every browser that you would ever need. Of course, if you are concerned about potential layout conflicts arising due to floating your primary layout divs, you may want to consider the absolute-positioning technique. In any case, having a choice when it comes to CSS layouts is definitely a good thing ;)

Footnotes

  • 1 Omitting the associated conditionally commented CSS rules for IE5mac will result in content that is repositioned outside of the browser window. However terrible, this only seems to happen when using an (X)HTML doctype. If your doctype happens to be HTML Transitional, this problem should not occur.

Related articles

About this article

This is article #410, posted by Perishable on Tuesday, September 25, 2007 @ 07:45am. Categorized as Presentation, Structure, and tagged with css, design, html, layout, markup, tips, tricks, xhtml. Updated on November 05, 2007. Visited 40830 times. 17 Responses »

BookmarkTrackbackCommentSubscribeExplore

« Five-Step Feed-Portfolio Makeover • Up • Notes and Tips for Better Social Bookmarking »


17 Responses

1 • September 28, 2007 at 6:36 pm — mlankton says:

Ok, not so much related, but I have a newbie question. For xhtml I know that we are supposed to use style=”float: left/right;” instead of align. What do we do with css if we want to center an img or ad instead of floating it left or right? Sorry to jack the comments down a tangent, but I’ve looked and haven’t been able to figure it out. Thanks

2 • September 30, 2007 at 9:36 am — Perishable says:

mlankton,

No problem at all!

If you are centering images in standards-compliant browsers (i.e., not Internet Explorer), then centering may be accomplished by using the following CSS and XHTML:

div.wrap img {
     margin: 0 auto;
     }

<div class="wrap">
     <img src="image.png" />
</div>

Basically, this method centers the image by setting its left and right margins to auto. Standards compliant browsers such as Firefox and Opera correctly interpret and apply the CSS, however IE does not. To center the image in our previous example for Internet Explorer, we would use this:

div.wrap {
     text-align: center;
     }

Actually, the previous code will center block-level elements in virtually all major modern browsers, including IE. The margin: 0 auto; rule is not currently needed. However, keep in mind that the text-align: center; rule is intended for inline elements, and thus is used improperly when applied to images.

It is also possible to center images using inline CSS, which may prove easier in certain situations. Simply wrap any image(s) in the following styled div:

<div style="text-align:center;">
     <img src="image.png" />
</div>

I hope that helps! ;)

3 • October 1, 2007 at 1:17 pm — mlankton says:

That is ridiculously helpful, thank you very much. I never intended to learn any css or xhtml, but being ocd I just can’t use other people’s templates, and also being ocd, I can’t sleep at night if my xhtml doesn’t validate.

4 • October 1, 2007 at 1:42 pm — Perishable says:

Well, you know how it goes..
Hanging out on the WWW with OCD will inevitably result in a case of CSS and XHTML ;)

5 • October 5, 2007 at 11:40 am — D. Greene says:

This is why I still use tables for some of my layouts, depending on the audience - I often encounter users that are accessing my sites with browsers more than six years old.

6 • October 6, 2007 at 8:11 pm — Perishable says:

Absolutely. Table-based layouts are definitely useful in specific situations, especially when cross-browser compatibility and branding are important. I have used table-based layouts on a number of sites, including my personal business site, Monzilla Media. Check out the source code for plenty of table-based goodness ;)

7 • October 11, 2007 at 12:49 am — Retec says:

Hello,
I tried to make the website which looks like this: http://www.verexelto.sk/testit/test.php

but i have 2 problems:

1. When i shrink page vertically enough, the content goes down behind the footer. (It should not)

2. When i shrink page horizonatally enough, using the scrollbar I cannot see the left side of the page.

I tried to use technique u mentioned , it works, but then i loos the other functionality of the page (footer olways on the bottom if content is smaller then window height …)

Is it possible to solve it?

Thanx in advance

8 • October 14, 2007 at 10:02 am — Perishable says:

Retec,
I noticed an abundance of position: absolute; declarations sprinkled throughout your CSS code. I would try experimenting with the relevant aspects of the technique described in the article above. As much as I would like to help visitors solve all of their specific CSS issues, unfortunately I simply do not have the time. However, I am more than happy to share general information, suggest possible clues and help troubleshoot whenever possible.

9 • October 15, 2007 at 6:12 am — mlankton says:

I need a hand. My site is not so much a blog, and I decided to ditch the left sidebar in favor of a top navbar.

I have not been able to center align the navbar no matter what I’ve tried. Help.

Also, would there be any way to make the navbar expand and contract so that users of all screen resolutions get something that looks ok? As is, I barely got this to work at 1024×768, and if that user isn’t viewing fullscreen, then my navbar wraps and screws up the site’s formatting.

Thanks

10 • October 15, 2007 at 10:12 am — Perishable says:

Hello mlankton, good to see you again :)

Those are some pretty specific CSS issues, I might say. Without a test case to look at, it would be very difficult to even know where to begin — there are millions of possible variables involved, any one of which possibly leading to a solution. If you setup and point to a test case that I can check out, I will gladly have a look and see if anything jumps out at me. As mentioned in a previous comment, digging into the nitty-gritty details of CSS code really zaps the time away, but I will definitely see what I can do.. ;)

11 • October 15, 2007 at 5:13 pm — mlankton says:

Thanks. I cobbled together a navbar yesterday at work. Today I found something I can modify to be more like what I want. You may still get an email from me with a stylesheet attached on the new one :)

12 • December 3, 2007 at 7:09 pm — Bender says:

I like how you don’t die if you have at least one ring.

13 • December 10, 2007 at 9:58 am — Christian says:

Thanks for the code Perishable.
It gives me inspiration for my current project. However, I still face some problems in combining codes from various source.
My goal is similar to the current Hotmail login page where:
*) the vertical distance of centered stuff to the browser’s border will shrink if I shrink the browser vertically and
*) the footer always stick to the bottom.
Do you have any suggestion?
or anyone?

Thanks in advance =)

14 • January 25, 2008 at 11:46 pm — Nishanthe says:

I had many problems with using CSS positioning. Your article helped to clarify it.
Thank you

15 • January 27, 2008 at 8:13 am — Perishable says:

You are welcome, Nishanthe — thank you for the positive feedback! :)

16 • February 7, 2008 at 3:10 pm — Jason says:

Thanks very much for your code and clarification on everything. I was having a wicket time on my /specs page with trying to get my images centered correctly. It would work in one browser and would be terrible in the next. In addition, I WAS using tables to try and break it apart and it still didn’t help.

It still isn’t PERFECT in IE but its very close and now works perfectly in firefox.

I really wanted to say thanks, you saved me a ton of headaches! Great job.

17 • February 7, 2008 at 3:11 pm — NicMartel says:

[Display: none;]problem!

2 DIVs, both float: right; DIV1 display: block; has a background picture and some wording. DIV2 display: none; has no background, and an <img> tag. DIV1 displays correctly with background, and DIV2 is not displayed as expected. I click a button that loads a picture, DIV1 is set to display: none and disappears, while DIV2 is set to display: block and appears with the picture where DIV1 was. ALL IS WELL. I click a second button that recals DIV1 by setting DIV2 to display: none and DIV1 to display: block, and PROBLEM: it shows ok except that the picture remains on the screen on top of DIV1??? I am not sure if DIV2 is still on top or if it is just the picture that remains??? It is as though IE(7) puts the img tag in a different context than its original (DIV2)? I would greatly appreciate a clue to get me out of this impass. Thank you.

Drop a comment


Set CSS to lite theme
Set CSS to dark theme