Vertically center a content area until it reaches a certain height?

My solution takes into account that you want your content to be centered on the whole page and not just "in the space below". I used negative margins to achieve this.

See the working example here:

http://jsfiddle.net/WkQzw/5/

HTML:

<div id="container">
    <div id="table">
        <div id="cell">
            <div id="content">Some content</div>
        </div>
    </div>
</div>

CSS:

#container {
    width: 100%;
    height: 100%;
    padding: 100px 0;
    margin-top: -100px;
}
#table {
    display: table;
    width: 100%;
    height: 100%;
    margin-top: 100px;
}
#cell {
    display: table-cell;
    vertical-align: middle;
}
#content {
    background-color: lightblue;
    width: 50%;
    margin: 0 auto;
}

Tested:

  • IE 9 Win7 --> WORKS
  • Chrome 30 Mac --> WORKS
  • Safari 7 Mac --> WORKS
  • Firefox 25 Mac --> WORKS

Update:

I used box-sizing: border-box; but Firefox required an additional -moz-box-sizing: border-box;. Now it works also in Firefox.


Pure CSS, not using Table

Another way to approach this would be to use CSS Grids. The align-items property allows you to vertically align grid contents easily, falling back to normal alignment when the content outgrows the cell.

An example:

function removeParagraph() {
  
  const p = document.querySelector('p')
  
  if (p)
    p.parentNode.removeChild(p)
    
}

function addParagraph () {

  const p = document.createElement('p')
  
  p.textContent = 'Bacon ipsum dolor sit amet drumstick rump swine capicola pastrami boudin t-bone, ground round filet mignon andouille frankfurter meatloaf.'
  
  document.querySelector('#content').appendChild(p)

}
html, body {
    
  height: 100%;
  
  margin: 0;
  padding: 0;
    
}

#wrapper {
  
  height: 100%;
  
  display: grid;
    
  grid-template-rows: 50px 1fr;
    
  align-items: center;
  
}

#space {
  
  height: 50px;
  width: 100%;
  
  border-bottom: 2px dashed red;
  
  color: red;
  
  text-align: center;
  
  line-height: 50px;
  
}

#content {
  
  width: 80%;
  
  background-color: lightblue;
  
  margin: 0 auto;

}

p {
  
  padding: 10px;
  margin: 0;

}
<section id="wrapper">
  <div id="space">
     <button onclick="removeParagraph()">remove paragraph</button>
     <button onclick="addParagraph()">add paragraph</button>
  </div>
  <div id="content">
    <p>Bacon ipsum dolor sit amet drumstick rump swine capicola pastrami boudin t-bone, ground round filet mignon andouille frankfurter meatloaf.
    </p>
  </div>
</section>

In the above example I'm using Javascript to allow you to add/remove paragraphs so that you can see the affect of growing the content. This is still a pure CSS solution to the problem.

Depending on your audience, support for CSS grids is pretty good.


Pure CSS, Reduced HTML

This is based off of ToniTornado's answer, but with far less wrappers needed.

See fiddle demo

HTML

<div id="container">
      <div id="content">Some content</div>
</div>

CSS (minimum for vertical positioning)

* {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}

body {
    display: table;
    padding-top: 100px;
    margin-top: -100px;
}

#container {
    display: table-cell;
    vertical-align: middle;
    padding-top: 100px;
}

Optional Vertical Centering Below Top Area

As the above fiddle showed, the above css centers the #content on the screen space. If you prefer to center on the space left below the top area, then adjust the body by removing the negative top margin and the #container by removing its top padding, like this fiddle and this css shows:

body {
    display: table;
    padding-top: 100px;
}

#container {
    display: table-cell;
    vertical-align: middle;
}