22

I have seen that while developing websites, vertically centering a container (of fixed height) inside a container of random height always comes as a nightmare for the web developer (at least, me) while when it comes to horizontal centering a container (of fixed width) inside a container of random width, the margin:0px auto; tends to serve an easy way out in the standard model.

When things can be as simple as that why doesn't CSS work out with the margin:auto 0px; when it comes to centering a container of fixed height inside a container of random height? Is there any specific reason to do so?

TylerH
  • 20,799
  • 66
  • 75
  • 101
ikartik90
  • 2,695
  • 6
  • 26
  • 38
  • 3
    http://phrogz.net/css/vertical-align/index.html offers some insight: "HTML layout traditionally was not designed to specify vertical behavior. By its very nature, it scales width-wise, and the content flows to an appropriate height based on the available width. Traditionally, horizontal sizing and layout is easy; vertical sizing and layout was derived from that." – justisb Dec 23 '11 at 20:12
  • true. but still, i have a gut feeling it could be much improved. it just feels awkward you can't use vertical-align:middle, unless the container is displayed as table-cell. – ptriek Dec 23 '11 at 20:19
  • 2
    @jblasco: I had already read the page you had referred to, but seems I didn't find the answer satisfactory. Reason: HTML was traditionally only intended to show/share simple textual data when it was devised at CERN, but then there have been so many changes when you compare the traditional HTML to HTML5. Then isn't it high time to adapt what promotes the ease of access? – ikartik90 Dec 23 '11 at 20:19
  • 1
    @ptriek: Well... `vertical-align` is meant for text, not boxes. Perhaps it could have been called `vertical-text-align` or something, but that's how it was first defined, so... – BoltClock Dec 23 '11 at 20:19
  • Anyway I suspect this has something to do with how vertical margins collapse. – BoltClock Dec 23 '11 at 20:23
  • 1
    @ikartik90 It's true the vertical standards could use an update to deal with the modern way web sites are built, where we want to control both horizontal and vertical content. But I also think that so many sites are currently built on the assumption that `margin: auto` does nothing vertically, that it may be "too late" to change it, without a lot of backlash. – justisb Dec 23 '11 at 20:48
  • @ptriek and @BoltClock - I would argue that `vertical-align` is perfect in this scenario. See my answer below. – Wex Dec 23 '11 at 21:08

4 Answers4

14

It's really less of a nightmare than you think, just don't use margins. vertical-align is really what you should rely on for fluid-height vertical centering. I threw together a quick demo to demonstrate my point:

* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
  text-align: center;
}

span {
  height: 100%;
  vertical-align: middle;
  display: inline-block;
}

#any-height {
  background: #000;
  text-align: left;
  width: 200px;
  height: 200px;
  vertical-align: middle;
  display: inline-block;
}
<span></span>
<div id="any-height"></div>

See: http://jsfiddle.net/Wexcode/jLXMS/

Rifky Niyas
  • 1,737
  • 10
  • 25
Wex
  • 15,539
  • 10
  • 64
  • 107
  • 1
    ok, you do have a point. vertical align isn't necessarily the nightmare, IE7 is, as was IE6. – ptriek Dec 23 '11 at 21:27
  • I've used vertical-align, but doesn't serve a satisfactory solution at most places. Reason: The problem with `vertical-align` is that it is not well compatible with all browsers. For reference [check this link](http://reference.sitepoint.com/css/vertical-align#compatibilitysection). So no points fella. :( – ikartik90 Dec 24 '11 at 05:37
  • 1
    [There are tools out there that can verify if something works on other browsers](https://browserlab.adobe.com/en-us/index.html), so you don't have to rely on charts that arbitrarily label things as buggy... I'm pretty sure that this works in all major browsers, and if you're looking for extended compatibility, you should check [this article](http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/). – Wex Dec 24 '11 at 18:42
  • 1
    One question- why're you using the empty span in your code? didn't get the reason. And though you might have a point where you stand, my question is not what should I use when I need to vertically center a container but why does `margin:auto 0px` not work to vertically center a container. Thanks for the Adobe tool though. Works great. – ikartik90 Dec 25 '11 at 18:26
  • 3
    Well, I figured I'd offer you an alternative. You use an empty `` because `vertical-align` aligns elements relative to their siblings. If an element has no siblings, it will not be vertically aligned. – Wex Dec 25 '11 at 18:51
  • Thanks @Wex. I waited all this time to accept this answer in anticipation that someone someday would respond with some better solution to the question as even though your way seems to work but its a mere fix and not a recommended way any webpage should be coded. Thanks anyway for your technique has at least served us with one way of fixing the auto vertical-alignment issue. – ikartik90 Feb 21 '13 at 17:58
11

The right answer for your question is that margin: auto 0 doesn't work the same way that margin: 0 auto works because width: auto doesn't work the same way height: auto does.

Vertical auto margin works for absolutely positioned elements with a known height.

.parent {
    position: relative;
}

.child {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    width: 150px;
    height: 150px;
    margin: auto;
}
user1602599
  • 119
  • 1
  • 2
2

Use flexbox parent

One of advantages of using margin: auto compared to justify-content: center / align-items: center is ability to scroll child item that is overflowing parent

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

.parent {
  display: flex;
  width: 100%;
  height: 100%;
}

.inner {
  width: 100px;
  height: 100px;
  background-color: green;
  margin: auto;
}
<div class="parent">
  <div class="inner">
  </div>
</div>
volodya7292
  • 454
  • 8
  • 20
0

CSS

.aligncenter{
      display: -webkit-box;
      display: -moz-box;
      display: box;
      -webkit-box-align: center;
      -moz-box-align: center;
      flex-align: center;
      -webkit-box-pack: center;
      -moz-box-pack: center;
      flex-pack: center;
}

HTML

<div class="aligncenter">
    ---your content appear at the middle of the parent div---
</div>

.aligncenter {
  display: -webkit-box;
  display: -moz-box;
  display: box;
  -webkit-box-align: center;
  -moz-box-align: center;
  flex-align: center;
  -webkit-box-pack: center;
  -moz-box-pack: center;
  flex-pack: center;
}
<div class="aligncenter">
  ---your content appear at the middle of the parent div---
</div>

Note

This CSS class work with almost all browsers

Rifky Niyas
  • 1,737
  • 10
  • 25
Mok
  • 35
  • 4
  • this does not work - probably because there is no such display property called "box". downvoted – MC9000 Mar 26 '18 at 02:36