Wednesday, August 24, 2005

Centering with CSS

After all that "I'm so great" in my post yesterday, I figured today would be a good time to show off how little I know about most things. :)

 

I'm an HTML/CSS neophyte. I can manage a basic page okay, but fancy-pants layout is well beyond me. CSS, in particular, is a topic whose further reaches I've never explored. Heck, I've barely wandered a few feet from its parking lot. (Although the FireFox EditCSS extension has made my HTML look loads better by making it easy to experiment.)  

 

One of the things I always have trouble with is figuring out how to center stuff. I'll slap a text-align: center on things sometimes, but that doesn't always accomplish what I want. So today I ran across this little nugget:

 

.centered80

{

  position: absolute;
  left: 10%;
  right: 10%
}

 

It gives me the ability to center something in the middle 80% of the page. It worked so well I wanted to record it here for my own future reference. I'm sure anyone that has spent any time with CSS already knows this (or a better version), but at least now I can find it again when I need it.

17 comments:

  1. Also a CSS neophyte, so take with a grain of salt, but doesn't it depend on the properties of the container (absolute, relative, flow, etc. -- a model that has never quite clicked with me)?

    ReplyDelete
  2. I have no idea! :)



    All I know is, it worked this time on a whole-page div I was using.

    ReplyDelete
  3. that position:absolute; could come back to haunt you if you use it elsewhere.



    Typically, you'd use this technique. Suppose a page with a main div (mainDiv) that you want to center...



    body { text-align: center;}

    #mainDiv {margin-left: auto; margin-right:auto; text-align: left;}



    The reason you have to add the text-align: left; is due to a flaw in IE.



    You can also do this approach with a div within a div or a table within a div.



    div.centered {text-align: center;}

    div.centered table {margin-left: auto; margin-right: auto; text-align: left;}

    ReplyDelete
  4. This also works well:

    #mainDiv {margin: 0 auto; width: 600px;}



    Set the width to whatever you want. The margin property is specified as top right bottom left (like a clock). If you only supply two values (top right) then the value for top is also the value for bottom and value for right is also value for left. Thus the rule above sets top and bottom margins to zero and auto margins left and right which has the effect of centering the div.

    ReplyDelete
  5. Phil - that's good to know. I think I understand everything there except the "auto" margins. I'll have to Google that and educate myself.



    Christian - in my case I wanted it to size to the browser, rather than dictating a size, but that's also good to know.

    ReplyDelete
  6. Haacked is right, you should try and avoid absolute positioning, as that will lead to more problems than it solves.

    To center your page in the middle 80% of the browser:

    BODY {width:100%;}

    #mainDiv {margin:0 auto;width:80%;}



    All the "auto" does is make shure margins on both sides are the same.

    ReplyDelete
  7. Cool - that seems like the way to do it, then. Now I am slightly less dumb than I used to be. :)



    What is it about absolute positioning that causes problems?

    ReplyDelete
  8. Of course, the other issue with this is that - now that I've actually tried it - it doesn't actually seem to work in IE. Although the width gets set to 80%, the main div doesn't wind up centered when I do this.

    ReplyDelete
  9. The 'issue' with absolute position is that it breaks the element out of the normal flow of the page. Think of it this way: pretend you have three divs one after the other. Normally they appear stacked. It may help to think of them as three cheerleaders stacked one on top of the other. Now take the middle cheerleader and pull her out of the stack and place her standing up 3 feet in front of the other girls (now only a stack of two). You have just absolutely positioned her but it affected the size/layout of the "stack". Note that I'm taking a lot of artistic license in this explanation of the box model, but absolute positioning breaks the element out of the normal flow and removes the space previously taken up by that element. Relative positioning, by way of contrast, is like breaking her out of the stack but putting an invisible box in her place for the top cheerleader to stand on. That is, it moves the element relative from its starting position but doesn't collapse the space taken up by the element. The rest of the surrounding layout behaves as if the element were still in its original location.

    ReplyDelete
  10. Right, that makes a lot of sense. So it seems to be the same problem that absolute paths have, especially when you've gone to all the trouble to use relative paths (as everyone should!) everywhere else in your application.



    In this case, if it's a single, top-level element that I'm centering, it would seem that I'm avoiding this specific issue. However, given that there are alternatives available, using them seems like a good idea. Now if only I can figure out how to make it work in IE...

    ReplyDelete
  11. Did you add the "text-align:center;" in the body tag? That's for IE. You don't need that for Firefox, but do with IE.

    ReplyDelete
  12. Ah - that did it. Slowly, the dim light of understanding begins to dawn.



    One of these days I'm going to have to devote myself to this stuff for a few weeks (or months (or years)) to really understand it.



    Thanks for explaining!

    ReplyDelete
  13. Hello! I want to center a div (containing a layout graphic) in the middle of the screen and then center a div (containing text) ON TOP of it and a bit farther DOWN the page, so that it looks like an IFRAME layout. I want to use divs instead of iframes. As you already know, when <em>overflow:auto</em> is applied to the div containing the text, it will scroll like an iframe does when the content is longer than the space provided.



    I used <em>margin-left:auto</em> and <em>margin-right: auto</em> on both divs to center them in the screen. I also used the <em>z-index</em> property, so one div would be on top of the other. I got it to work perfectly in Firefox and it looked GREAT, but when I tried to view the same page in IE, the content div was underneath the layout div and not centered. Arrrrggghhhhhh!



    I don't want to use absolute positioning, because if the browser window is resized, or if the viewer is using a different resolution, the divs wont be centered. What can I do? Please help!

    ReplyDelete
  14. I have absolutely no idea, myself: I'm not much of a HTML guy. Hopefully someone else can answer your question, though.

    ReplyDelete
  15. Although div centering works in full browser, when you shrink the browser or use it in a low resolution some of the div content is unviewable. How is it possible to view this.



    Go to my site if you would please and see if it is fixable.



    http://www.freeflycorner.com

    ReplyDelete
  16. I have figured out a full-proof, cross-browser (including ie 6) method to completely center an object on the screen no matter the resolution or screen size using javascript and the prototype library.



    You give the body tag an id name and set it to position:absolute and the width and height to 100%;

    Then you put whatever you want centered in a div tag and give that an id. Set it to position:absolute.



    Using the prototype getHeight and getWidth functions on your "body" id will return the width and height of the users screen no matter the size or resolution.



    Subtract the width and height (using the prototype functions if necessary) on the inner div and then subtract that number by 2. What you are left with is a number that represents half of the remaining distance leftover after the inner div is on the screen. set the left and top of the inner div to those numbers and 'tada'







    ReplyDelete