1

I am trying to position a div at the center of viewport.

Here's what I did so far.

HTML

<html>
    <head>
        <title>TEST</title>
    </head>
    <body>
        <div id="header">Some header stuff here.</div>
        <div id="wrapper">
            <div class="spacer"><!-- avoid overlapping of content by header --></div>
            <div id="content">Stuff to be centered horizontally and vertically.</div>
            <div footer="spacer"><!-- avoid overlapping of content by footer --></div>
        </div>
        <div id="footer">Some footer.</div>
    </body>
</html>

CSS

html, body{
    height:100%; /*Setting height to 100% in order to make min-height:100% to work on wrapper.*/
}
#header{
    height:70px;
    width:100%;
    position:fixed;
    top:0;
    left:0;
}
#wrapper{
    min-height:100%;
    width:100%;
    margin-bottom:-70px; /*Equal to footer's height*/
}
#content{
    /* Exact height is not known.*/
    width:250px;
    position:absolute;
    top:50%;
    left:50%;
    margin:0px 0px 0px -125px; /* Top margin?? */
}
#footer{
    height:70px;
    width:100%;
    position:relative;
    bottom:0;
}
div.spacer{
    height:70px;
}

Now I have two problems.

  1. Since height is unknown, how to position the div#content to exact center because I can't set a negative margin-top.

  2. Even if the height of #content was known and setting margin-top could have worked, the method will fail as soon as the viewport's height is less than that of div#content's since header and footer will overlap #content.

How to fix this?

ashu
  • 1,756
  • 4
  • 22
  • 41

2 Answers2

3

Use css calc to have the height of your #wrapper 100% minus the height of your footer and header (make sure you body and html have a height of 100%). In that #wrapper you use flexbox to display your #content centered.

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

header {
    background-color:orange;
    height:70px;
}

#wrapper {
    align-items:center;
    background:blue;
    display:flex;
    /* 100% minus height of both header and footer */
    height:calc(100% - (70px + 70px));
}

#content {
    background:white;
    margin:auto;
    width:250px;
}

footer {
    background-color:orange;
    height:70px;
}
<header></header>
<div id='wrapper'>
    <div id='content'>Content</div>
</div>
<footer></footer>
Marwelln
  • 28,492
  • 21
  • 93
  • 117
2

Have a look at the following. It centers a div perfectly in the center.

EDIT Applied some javascript to dynamically position the content centered after the page has rendered.

/***************/

 window.onload = function() {
   var content = document.getElementById("content");
   content.style.height = content.clientHeight + "px";
   content.style.position = "absolute";
 };
   html,
   body {
     height: 100%;
     /*Setting height to 100% in order to make min-height:100% to work on wrapper.*/
   }
   #header {
     height: 70px;
     width: 100%;
     position: fixed;
     top: 0;
     left: 0;
   }
   #wrapper {
     min-height: 100%;
     width: 100%;
     margin-bottom: -70px;
     /*Equal to footer's height*/
   }
   #content {
     position: relative;
     top: 0;
     bottom: 0;
     left: 0;
     right: 0;
     margin: auto;
     width: 140px;
     height: auto;
     background: #eee;
   }
   #footer {
     height: 70px;
     width: 100%;
     position: relative;
     bottom: 0;
   }
   div.spacer {
     height: 70px;
   }
<div id="header">
  Some header stuff here.
</div>
<div id="wrapper">
  <div class="spacer">
    <!-- avoid overlapping of content by header -->
  </div>
  <div id="content">
    Stuff to be centered horizontally and vertically.
  </div>
  <div footer="spacer">
    <!-- avoid overlapping of content by footer -->
  </div>
</div>
<div id="footer">
  Some footer.
</div>
Daniel
  • 4,816
  • 3
  • 27
  • 31
  • I am not sure how does it solve my second problem? Avoiding the overlapping? – ashu Feb 14 '15 at 18:38
  • And yeah, just tried it. your solution doesn't work with unknown height. Instead it stretches the child to match parent's height. – ashu Feb 14 '15 at 18:45
  • The feature you seek can not be done with pure CSS. Since your height is dynamic, you will also need to respond dynamically. this can be done with a little javascript. i have adapted the answer to make it respond that way. – Daniel Feb 14 '15 at 19:28
  • 1
    +1 but couldn't mark it as accepted because if I would want to use Javascript, I wouldn't be posting this on SO because I already have the JS version running. :) – ashu Feb 14 '15 at 20:51