Can't center div vertically

I don’t understand why I can’t center my div vertically. When I do top 50%, nothing happens, that’s the part I don’t get. If you guys have an even better way to center vertically, please let me know. Thanks.

body
{
background:white;
position: relative;
height:100%;
}

#wrapper
{
position:absolute;
width:920px;
height:505px;/image height/
top:50%;
margin-top: -252px;
margin-left: auto;
margin-right:auto;
border: 2px solid #e00;
font-family:helvetica;
font-size: 12px;
color: #666;
line-height:19px;
padding:0;
}

Hi,
Have a look through Paul’s Easy Vertical Centering article at search-this.com

Be sure to read on down past “The Old Way” (better yet read the whole article) and then you will find “The Fix”.

“The Fix” involves a float before the wrapping div with a negative top margin half the height of your centered div.

http://www.pmob.co.uk/search-this/center2.htm

Here is your wrapper dimensions set up with a quick test case :wink:
(actually I made it 504px tall so it would divide equally)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Vertical Centered</title>

<style type="text/css">
html,body{
    height:100&#37;;
    margin:0;
    padding:0;
}
body{
    background:#FFF;
    text-align:center;
    min-width:924px;
    min-height:508px;
}

#vertical{
    float:left;
    height:50%;
    margin-top:-254px;/* half wrapper total height with borders*/
    width:100%;
}
#wrapper {
    clear:both;
    width:920px;
    height:504px;/*image height*/
    margin:0 auto;
    overflow:auto;/*insure access to content*/
    background:#CCC;
    border:2px solid #E00;
}
</style>
</head>
<body>

<div id="vertical"></div>
<div id="wrapper">
    <p>Lorem ipsum dolor sit amet consectetuer tincidunt nulla orci tristique Phasellus. 
    Ridiculus metus Curabitur dignissim fermentum purus sit pellentesque Ut id quis. Nam orci 
    turpis Nunc iaculis sociis odio pede pede.</p>
    <p>Curabitur facilisis mauris Nam laoreet Vestibulum nibh scelerisque felis leo at. 
    Pretium vitae Phasellus hendrerit augue tempus interdum nibh convallis Curabitur Sed. Dolor 
    eu metus est hendrerit in justo Nunc semper felis sit. Aliquam tortor netus.</p>
</div>

</body>
</html>

Thanks Rayzur, that was extremely helpful.
It took a while of trying to understand it, but now I finally grasped the concept.

There’s just one small thing I don’t quite get:

I understand that if the viewport gets small enough, the float will be outside the viewport but the following element will be contained within it, and that it will be lined up right against the top.

What I don’t understand is how setting a min. height leaves a space between the top of the viewport and the top of the following element (which it does).

I understand that setting the min. height means that the body of the page cannot get smaller than a certain size, thereby adding scroll bars to the viewport if it gets too small. I just don’t understand how that can stop the following element from lining up right against the top of the body when the viewport gets smaller. From what I understand, the floating box above it is still going to move beyond the top of the body, and the only thing that should stop the following element from going up further is the top of the body, not anything else.

So why will there be a space in between?

Hi,
The code I posted above does not suffer from the problems you mentioned. More than likely you did not zero out your default body margins/paddings.

Look back at my code and you will see this.


[B]html,body[/B]{
    height:100&#37;;
[COLOR=Blue]    margin:0;
    padding:0;[/COLOR]
}

That should take care of your problem :slight_smile:

oops, I changed the min height from 508 to 608.

But that raises another question.

In your example, the 50% height of the float is based on the height of the body element. If I changed the min height of the body to 1000px, the height of the float is going to be 500px, no matter how small my viewport is. So that gap between the top of the page and the top of the wrapper box is always going to be (height of float) minus (the negative margin of float) no matter how small the viewport is. I understand that’s why the gap stays constant.

But if this logic applies, how come in the ‘search-this’ page by Paul-OB, in the first or second example he gave, the wrapper box disappears to the top?

Let’s take his second code:

<style type=“text/css”>

  html,body{

      height:100%;

      margin:0;

      padding:0;

  }

  body{


      text-align:center;

      min-width:626px;

      min-height:1000px;

  }

  #vertical{

      position:absolute;

      top:50%;

      margin-top:-198px;/* half main elements height*/

      left:0;

      width:100%;

  }

  #hoz {

      width:624px;

      margin-left:auto;

      margin-right:auto;

      height:394px;

      border:1px solid silver;

      background:#666;

      overflow:auto;/* allow content to scroll inside element */

      text-align:left;

  }

h1 {color:#fff;margin:0;padding:0}

</style>

</head>
<body>

  &lt;div id="vertical"&gt;

      &lt;div id="hoz"&gt;

          &lt;h1&gt;Content goes here&lt;/h1&gt;

      &lt;/div&gt;

  &lt;/div&gt;

</body>
</html>

Above, I changed the min-height to 1000px. So if the logic follows, because the top property of the vertical div is set to 50%, which to my understanding is 50% of the height of the body (1000px), the vertical div should be 500px below the top, and then minus it’s negative margin of 198px. And that should stay the same no matter how small the viewport becomes, because the body height will be 1000px at minimum no matter how small the viewport gets and the vertical div will always be 50% of that height (500px) minus 198px. It should stay constant no matter how small the window gets.

At first I thought the reason it disappears when the viewport gets smaller is because the ‘top’ property (which has a value of 50%) of the vertical div is based on the viewport size, and logically when the viewport gets smaller, the viewport height also gets smaller, which causes the value of ‘top:50%’ to get smaller as well. And when it eventually becomes smaller than the negative margin of -198px, it pulls the box above the page.

But then I realized it’s actually based on the body size, and the body size doesn’t change when the viewport gets smaller. So why does the content still disappear off the top of the page? Where did my logic go wrong?

In your example, the 50% height of the float is based on the height of the body element. If I changed the min height of the body to 1000px, the height of the float is going to be 500px, no matter how small my viewport is.

So why does the content still disappear off the top of the page? Where did my logic go wrong?

[B]html,body[/B]{
          [B]height:100%;[/B]
          margin:0;
          padding:0;
      }
      [B]body[/B]{
          text-align:center;
          min-width:626px;
          [B]min-height: total div height;[/B]
      }

No, the body has a defined height:100% , The min-height property just tells it when to stop and induce a scrollbar. That min-height should be the total height of your centered div including borders.

The 50% height float is getting it’s height from the html,body height:100% since it is a direct child.
Then it gets a negative top margin that is half of the centered div’s total height.

My test case breaks it down as simple as it can get. :wink:

Yeah, I got that part. Maybe my previous reply was too long, I didn’t make myself clear.

I understand the min height thing. But why does Paul OB’s first two examples cause the content to move above the viewport?

In his first example, his body min height is set to 400px, and the ‘top’ is set to 50% for the ‘vert-hoz’ div, with a margin-top of -198px. Which means that the vert-hoz div should only go as far up to the top of the body and no further (200px -198px - (2 x 1px for the borders)) = 0px. It should not go past 0px to become negative (above the body) b/c 50% of the min height of the body is always 200px, and therefore that formula doesn’t change no matter how small one minimizes the window.

In other words, the size of the window should have no effect on the content being pushed up and above the screen (b/c top:50% is based on body height, not viewport height), yet it does. Why?

At first I thought the reason it disappears when the viewport gets smaller is because the ‘top’ property (which has a value of 50%)

In other words, the size of the window should have no effect on the content being pushed up and above the screen (b/c top:50% is based on body height, not viewport height), yet it does. Why?
You confused me because I thought you were still talking about the float method, sorry if I misread your post.

Those first two methods are obsolete for the very reason that you have discovered. :slight_smile:

They slide under the viewport (disappear) because the parent is an absolute positioned element. That is an adverse side effect of AP but it can be helpful sometimes if you want something to intentionally slide off the page. Fixed position elements will slide behind the viewport also, they are a specialized form of AP. Once they disappear they cannot be brought back with a scrollbar.

The float method has superceded the former methods because it keeps the content from disappearing completely and accessible via scrolbar.

The use of absolute positioning was actually the answer to Quiz #24/ quiz-1
If you were to run that “solution code” in your browser you will see the side divs slide off the screen when the viewport width is reduced.

The same thing happens in this Fixed Positioned Demo. Though that one is not intentional but rather just the behavior to which there is no cure because it is removed from the normal page flow.