42

I have a <div id="wrapper"> container in which my whole site content will be present. I have tried to make the div center vertically and horizontally by using css property like margin:0 auto; on #wrapper.

#wrapper
{
 width:500px;
 height:500px;
 margin:0 auto;
 background:#f7f7f7;
}

By using above css i can make the div in (top center) of screen but how to make it center(vertically). when i zoom out in firefox my div is going to zoom out in top center but what i want it should be always present in the center of screen from both vertically and horizontally.

Can any one suggest me how can i get the layout like that.

Thanks in advance.

  • you can have a look at this link http://stackoverflow.com/questions/659677/vertically-center-in-viewport-using-css/42204490#42204490 – vikas etagi Feb 13 '17 at 12:56

6 Answers6

59
#wrapper
{
 width:500px;
 height:500px;
 margin:0 auto;
 background:#f7f7f7;
 position:absolute;
 left:50%;
 top:50%;
 margin-left:-250px;
 margin-top:-250px;
}

Demo: http://jsfiddle.net/fJtNQ/

Why is this working?

Well, basically you have an absolute positioned element inside the dom. It means that you can position it wherever you want and if you don't have a relative positioned element as parent, left and top will be the distance from the document's left/top origin.

Assigning left:50% and top:50% enables this element to be positioned always in the center of the screen, but in the center you will find the top left corner of the element.

If you have fixed width/height, you can easily 'translate' the point in the center to be actually the center of the wrapper div by giving negative margin-left and margin-top (therefore with the help of some extremely easy basic math their values will be -(width/2) and -(height/2))

EDIT

You can also easily center by using flexbox, plus (a big one) you don't need to specify w/h, i.e.:

body { /* can also be whatever container */
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
}

#wrapper {
  /* whatever style u want */
}

demo: https://jsfiddle.net/00utf52o/

stecb
  • 14,478
  • 2
  • 50
  • 68
  • 1
    In the past, I've used methods where I've put the wrapper into another container element. Centering the outer vertically and the inner horizontally. This is much nicer. – Dan Hanly Mar 08 '12 at 17:59
  • I normally don't like when people just post a JSFiddle and the code without an explanation just to be the fastest to answer, but it is a good answer, +1 – ShadowScripter Mar 08 '12 at 18:01
  • U're right, I was with mobile, and as far as the solution was pretty straightforward I just answered it in 1 sec. Gonna explain it asap :) – stecb Mar 08 '12 at 18:06
  • @stecb Remember, just because he accepted it doesn't mean you shouldn't explain what's going on. At least put in a link to a tutorial that does vertical alignment. It's good to have references. ;) – ShadowScripter Mar 08 '12 at 18:11
  • that's a way that works, however it is not recommended as best practice, because if your viewport is smaller than the element you center you will not see the whole element and you won't be able to scroll! So, be careful with this! Better is to use margin:auto, e.g. – Helmut Sep 21 '12 at 13:18
  • ** If you have fixed width/height ... ** Is there a way to do this for varying heights. I am trying to position an image vertically center and with 100% width in mobile responsive views. – musafar006 Dec 04 '15 at 07:15
  • @dreamster yep u can, by using flexbox is pretty straightforward: http://jsfiddle.net/6wb420m0/2/ – stecb Dec 04 '15 at 08:54
  • @stecb but that stretches the image. I found a solution. Take a look: http://stackoverflow.com/a/34084294/2733146 – musafar006 Dec 04 '15 at 08:59
  • @dreamster ah I got what u meant. Do also a fiddle ;) – stecb Dec 04 '15 at 09:25
  • 2018 update: just used the flexbox method and it works just fine. This should be the solution in almost all cases in my opinion. – Syknapse Feb 26 '18 at 09:14
38

@stecb's answer works fine if you're working with fixed width/height.

To position a div or an image vertically at the center in all viewports and make it responsive, use this:

#elem-to-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

I just replaced margin-left and margin-top with transform.

If you want a margin surrounding the element, use this:

#outer-elem {
    width: 100%;
    height: 100%;
    padding: 30px;
    background: #fafafa;
    position: relative;
}
#elem-to-center {
    width: calc(100% - 60px);
    max-height: calc(100% - 60px);

    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

JSFiddle | Source

I found this useful even in responsive views.

musafar006
  • 931
  • 11
  • 22
  • `#elem-to-center` works very well for large viewports. But it breaks for smaller viewports. How can this solution be translated to smaller viewports? – Gitau Harrison Oct 18 '20 at 00:30
  • @GitauHarrison I just checked the JSFiddle and couldn't reproduce. Maybe your styling is different. Can you please briefly explain what exactly you are trying to achieve? A fiddle will help. – musafar006 Oct 20 '20 at 13:55
16

Here is a solution for those who need to center a child div relative to viewport and not "relative to parent div". Other solutions mentioned here do not work in this case as they tend to make the child div center relative to the parent div.

<div id="container">
  <div id="wrapper">Always center, No matter the parent div's position</div>
</div>

#wrapper {
 width:300px;
 height:300px;
 margin:0 auto;
 background:green;
 position:fixed;
 left:50%;
 top:50%;
 margin-left:-150px;
 margin-top:-150px;
}

#container {
  display: block;
  position: absolute;
  width: 400px;
  height: 400px;
  border: 1px solid red;
  bottom: 0;
  left: 0;
}

demo here http://jsbin.com/yeboleli/2/edit?css,output

rkrara
  • 442
  • 1
  • 6
  • 17
2

I use jQuery

$(window).resize(function(){

    $('.className').css({
        position:'absolute',
        left: ($(window).width() - $('.className').outerWidth())/2,
        top: ($(window).height() - $('.className').outerHeight())/2
    });

});

// To initially run the function:
$(window).resize();
Hupperware
  • 979
  • 1
  • 6
  • 15
  • 5
    Using JavaScript when u can solve problems by css only should be always avoided. – stecb Mar 08 '12 at 17:59
  • 1
    @stecb Not only is it something to be avoided, but it also makes you look uncool. CSS has always been for the cool kids. – ShadowScripter Mar 08 '12 at 18:05
  • 1
    So should shortening the word "you". Using CSS for something that may be dynamic and cannot be solved through CSS should be avoided. Sure, I could center a square too... but if that square becomes something different... – Hupperware Mar 08 '12 at 18:07
  • That's another problem :P ..this is a general solution for the case of an element with fixed w/h. If different cases can't be solved by css I'd prefer to change the layout instead of opting for JS (that IMO shouldn't be used to solve layout problems). – stecb Mar 08 '12 at 18:18
  • 2
    The CSS solution requires that you know the width and height of the element. In responsive layouts the width and height of an element changes. – Tony Topper Jul 30 '14 at 16:09
  • 2
    To add to this.. if you want to properly vertically center elm to viewport regardless of scroll position you need to take into account their current vertical scroll position and add that to the top value. top: $('.elm').css('top', ($(window).height() - $(elm).outerHeight())/2 + $(window).scrollTop()) – Jose Browne Apr 07 '15 at 21:10
1

The simplest and the cleanest way to do this would be by setting the height, margin (and width, if you want) using viewport sizes.
Say you want the height of you container to occupy 60% (60vh) of the screen, you can divide the rest (40vh, since total height of the viewport = 100vh) equally between the top and the bottom margin so that the element aligns itself in the centre automatically.
Setting the margin-left and margin-right to auto, will make sure the container is centred horizontally.

.container {
         width: 60vw; /*optional*/
         height: 60vh;
         margin: 20vh auto;
         background: #333;
 }
<div class="container">
</div>
Rocks
  • 1,145
  • 9
  • 13
0

Consider using display: table coupled with display: table-cell; vertical-align: middle on a separate element. Because CSS does not have semantic meaning, it's an acceptable solution.

I worked up an example for you: http://dabblet.com/gist/2002681

The only downside is that requires a little more markup than some other solutions, but it contracts and expands with the content.

chicagoing
  • 326
  • 2
  • 5