views:

467

answers:

5

I can horizontally align a div and all the content looks nice. Looking to vertical align a div that does not contain any tables. I tried setting margin positions to some negative values inside of the #container but that sort of worked. I know CSS isn't supporting this yet?

Here is my markup:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html lang="en">
<head>
<title>
</title>
</head>
<style type="text/css">
body
{
    background: #000000 url(body_bg.gif) repeat-x;
    text-align: center;
}

#container 
{ 
    margin:0 auto;
    width:968px;
    text-align: left;

}

#toptab
{
    background: url(panel_top.png);
    height: 14px;
    width: 968px;
}

#middletab
{
    background: url(panel_bg.png);
    width: 968px;
}

#data
{
    width:948px; /* 948 for the box plus we need 20 more px to handle the padding */
    padding-left:10px; 
    padding-right:10px;
}

#bottomtab
{
    background: url(panel_bottom.png);
    height: 14px;
    width: 968px;
}
</style>
<body>
    <div id="container">
     <div id="toptab"></div>
     <div id="middletab">
      <div id="data">
       The quick brown fox jumped over the big red bear.  The quick brown fox jumped over the big red   

       bear.  The quick brown fox jumped over the big red bear.  The quick brown fox jumped over the big  

         red bear.  The quick brown fox jumped over the big red bear.  The quick brown fox 

jumped over the            big red bear.  The quick brown fox jumped over the 

big red bear.  The quick brown fox jumped over the     big red bear.  The quick brown fox jumped over the 

big red bear.  The quick brown fox jumped over the     big red bear.  The quick brown fox jumped over the 

big red bear.  The quick brown fox jumped over the big     red bear.  The quick brown fox jumped over the big 

red bear.  
      </div>
     </div>
    <div id="bottomtab"></div>
    </div>
</body>
</html>

Take a close look at the #container, this is the container I want to align vertically. The effect would force the entire div and all sub divs to not only be horizontally aligned but also vertically. I know this is possible and I know andy budd posted such a solution but it doesn't seem to work for me!

Here is what the page currently looks like:

alt text

So it looks great horizontally but now I need it to center vertically in the page.

+3  A: 

Have a look at Vertical Centering With CSS or Vertically center content with CSS or CSS Vertical Centering. Method 3 of first reference is the same as CSS vertical center using float and clear.

And it's surely a good idea to test the result with a service like browsershots.org


EDIT: I modified your CSS and markup to implement Method 3:

css:

* {
  margin:0;
  padding:0;
}

html,
body {
  height: 100%;
}

body {
  text-align:center;
}

#floater {
  float: left;
  height:50%;
  margin-bottom: -100px;
}

#container
{
  clear:both;
  position: relative;
  margin: 0 auto;
  width:968px;
  text-align: left;
  height: 200px;
}

...

markup:

<body>
<div id="floater"></div>
<div id="container">

...

The drawback I see in this method is that with CSS you have to know in advance the height of your content, so that you can apply a negative margin of half this height to the floater. In the example I chose 200px.

See it in action.

Gregory Pakosz
I don't need any articles I've read plenty. I can't seem to get it to work with negative margin values.
JonH
If themeforest is ever unavailable, this response will be inadequate. Do you mind migrating the instructions over into your answer, and give credit to the original authors. That way people don't have to bounce from page to page to weigh the value of your response?
Jonathan Sampson
@JonH > give a man a fish...
Gregory Pakosz
@Jonathan > good point although I don't like ripping stuff from others :/
Gregory Pakosz
@Gregory ok ok at least +1 for the hyperlinks...
JonH
@Gregory: Give credit, and no harm is done :)
Jonathan Sampson
funnily enough, I got upvoted by @JohnH for the links, and while I was busy implementing one of the techniques linked I got downvoted
Gregory Pakosz
Not by me gregory!!! I thank you for your time and effort..I wish I could accept 2 answers!
JonH
It's not that important. It's just that I myself don't downvote an answer when there is obviously nothing wrong in it. If I feal it's not good enough I just don't vote up. Good luch with your site
Gregory Pakosz
I agree I've always wished SO had a section inside the person's profile to show you who was the latest votes whether up votes or down votes. It would help to get feedback on a downvote. For instance, force the user to leave a comment if he / she is downvoting.
JonH
and ironically my first thought was to suggest using jQuery :D
Gregory Pakosz
A: 

There are a few ways to do this, all with compromises.

  • Use position:absolute, a fixed height, and overflow:auto.
  • Use display:table, display:table-cell, and vertical-align:middle
  • Use javascript

I think option #2 is pretty good.

edit: I don't think option 2 will work in IE. You may be stuck with javascript if you want to keep the height dynamic.

Peter Di Cecco
Compromises cross browser compatibility: the whole IE family to be precise.
cballou
@cballou, ya I just thought of that and was editing my post as you were leaving your comment :P
Peter Di Cecco
+2  A: 

Unless you have the ability to explicitly set the height of your container (which doesnt look like that's the case), there is no cross browser solution for vertically centering your DIV container.

Using a table is completely viable, but you have noted that this cannot be used.

If javascript is an option, we could easily remedy this for you. A jQuery plugin already exists for vertically aligning a container.

(function ($) {
    // VERTICALLY ALIGN FUNCTION
    $.fn.vAlign = function() {
        return this.each(function(i){
            var ah = $(this).height();
            var ph = $(this).parent().height();
            var mh = (ph - ah) / 2;
            $(this).css('margin-top', mh);
        });
    };
})(jQuery);

And you would vertically align a DIV block like so:

$('#example').vAlign();

Taken from Simple Vertical Align Plugin.

cballou
@cballou There is no way that I'd be able to tell the height of the container, it could vary :(. But if I assume the most its going to be is 500px say. Using the markup provided what could I do ?
JonH
I tried this with no luck#container { margin:0 auto; width:968px; text-align: left; position:absolute; top: 50%; left: 50%; height:484px; margin-top: -9em; /*set to a negative number 1/2 of your height*/ margin-left: -15em; /*set to a negative number 1/2 of your width*/}
JonH
@JonH: If it doesn't have a *fixed* height, you won't be able to make it vertically center without javascript.
Tatu Ulmanen
@Tatu I understand that, that is why I said assume it is...
JonH
@cballou +1 for that! My only question is I haven't worked much with JQuery. I understand the function needs to be within a head tag and do I just include jquery.js ?
JonH
Got it to work..learned a bit about jquery too!
JonH
A: 

If your main container's height is fluid, your only reliable choice is to use JavaScript ("reliable" is debatable here, of course). In JavaScript, you must first find the height of the container, then the window height and adjust the top offset accordingly. Here's how you'd do it in jQuery:

$(function() {
    $(window).resize(function() {
        var top = $(window).height() / 2 - $('#content').height() / 2;
        top = top < 0 ? 0 : top;
        $('#content').css('top', top);
    });
    $(window).resize();
});

And the CSS to make it work:

#content {
    position: absolute;
    /* Everything else is optional: */
    width: 960px;
    margin: 0 auto;
}

And the HTML:

...
<body>
    <div id="#content">Content here</div>
</body>
</html>

That's still quite simple, and will work if the user has JavaScript enabled.

Tatu Ulmanen
Unfortunately im not really a js guy...How does the page know to use that jquery function?
JonH
My only gripe with this function is it will only properly work if the element is a direct child of the BODY tag. The plugin I posted utilizes it's parent container for calculating the centered position.
cballou
+1  A: 

With pure CSS, this is only possible if the div has a fixed height. You can then position it absolute and set its top and left to 50% and the margin-top and margin-left to the negative half of its width and height respectively.

Here's an SSCCE, just copy'n'paste'n'run. The border is purely presentational, the remaining styles are required.

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 1909753</title>
    </head>
    <style>
        #content {
            position: absolute;
            width: 300px;
            height: 200px;
            top: 50%;
            left: 50%;
            margin-left: -150px; /* Negative half of width. */
            margin-top: -100px; /* Negative half of height. */
            border: 1px solid #000;
        }
    </style>
    <body>
        <div id="content">
            content
        </div>
    </body>
</html>

If there is no means of a fixed height, then you'll need to grasp Javascript and live with the fact that client will see the div quickly being shifted to middle during page load, which might cause a "wtf?" experience.

BalusC
+1 for that one
JonH