[html] Why is vertical-align: middle not working on my span or div?

I'm trying to vertically center a span or div element within another div element. However when I put vertical-align: middle, nothing happens. I've tried changing the display properties of both elements, and nothing seems to work.

This is what I'm currently doing in my webpage:

_x000D_
_x000D_
.main {_x000D_
  height: 72px;_x000D_
  vertical-align: middle;_x000D_
  border: 1px solid black;_x000D_
  padding: 2px;_x000D_
}_x000D_
    _x000D_
.inner {_x000D_
  vertical-align: middle;_x000D_
  border: 1px solid red;    _x000D_
}_x000D_
    _x000D_
.second {_x000D_
  border: 1px solid blue; _x000D_
}
_x000D_
<div class="main">_x000D_
  <div class="inner">_x000D_
    This box should be centered in the larger box_x000D_
    <div class="second">Another box in here</div>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Here is a jsfiddle of the implementation showing that it doesn't work: http://jsfiddle.net/gZXWC/

This question is related to html css

The answer is


You should put vertical-align: middle on the inner element, not the outer element. Set the line-height property on the outer element to match the height of the outer element. Then set display: inline-block and line-height: normal on the inner element. By doing this, the text on the inner element will wrap with a normal line-height. Works in Chrome, Firefox, Safari, and IE 8+

_x000D_
_x000D_
.main {_x000D_
    height: 72px;_x000D_
    line-height:72px;_x000D_
    border: 1px solid black;_x000D_
}_x000D_
.inner {_x000D_
    display: inline-block;_x000D_
    vertical-align: middle;_x000D_
    line-height: normal;_x000D_
}
_x000D_
<div class="main">_x000D_
    <div class="inner">Vertically centered text</div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Fiddle


Here you have an example of two ways of doing a vertical alignment. I use them and they work pretty well. One is using absolute positioning and the other using flexbox.

Vertical Align Example

Using flexbox, you can align an element by itself inside another element with display: flex; using align-self. If you need to align it also horizontally, you can use align-items and justify-content in the container.

If you don't want to use flexbox, you can use the position property. If you make the container relative and the content absolute, the content will be able to move freely inside the container. So if you use top: 0; and left: 0; in the content, it will be positioned at the top left corner of the container.

Absolute positioning

Then, to align it, you just need to change the top and left references to 50%. This will position the content at the container center from the top left corner of the content.

Align in the middle of the container

So you need to correct this translating the content half its size to the left and top.

Absolute centered


In case you cannot rely on flexbox... Place .child into .parent's center. Works when pixel sizes are unknown (in other words, always) and no problems with IE9+ too.

_x000D_
_x000D_
.parent { position: relative; }_x000D_
_x000D_
.child {_x000D_
    position: absolute;_x000D_
    top : 50%;_x000D_
    left: 50%;_x000D_
    -ms-transform: translate(-50%, -50%);_x000D_
    transform    : translate(-50%, -50%);    _x000D_
}
_x000D_
<div class="parent" style="background:lightyellow; padding:6em"> _x000D_
  <div class="child" style="background:gold; padding:1em">&mdash;</div> _x000D_
</div>
_x000D_
_x000D_
_x000D_


Just put the content inside a table with height 100%, and set the height for the main div

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>

This is a modern approach and it utilizes the CSS Flexbox functionality. You can now vertically align the content within your parent container by just adding these styles to the .main container

.main {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

And you are good to go!


HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

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

We set the parent div to display as a table and the child div to display as a table-cell. We can then use vertical-align on the child div and set its value to middle. Anything inside this child div will be vertically centered.


I used this to align everything in the center of the wrapper div in case it helps anyone - I found it simplest:

_x000D_
_x000D_
div.wrapper {_x000D_
  /* --- This works --- */_x000D_
  display: flex;_x000D_
  /* Align Vertically */_x000D_
  align-items: center;_x000D_
  /* Align Horizontally */_x000D_
  justify-content: center;_x000D_
  /* --- ---------- ----- */_x000D_
  width: 100%;_x000D_
  height:100px;_x000D_
  background-color: blue;_x000D_
}_x000D_
div.inner {_x000D_
  width: 50px;_x000D_
  height: 50px;_x000D_
  background-color: orange;_x000D_
}
_x000D_
<div class="wrapper">_x000D_
  <div class="inner">_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


To vertically center a span or div element within another div, add position relative to parent div and position absolute to the child div.Now the child div can be positioned anywhere inside the div.Example below centers both horizontally and vertically.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

css:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

here is a great article of how to vetical align.. I like the float way.

http://www.vanseodesign.com/css/vertical-centering/

The HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

And the corresponding style:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}

It's simple. Just add display:table-cell in your main class.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Check out this jsfiddle!


Here is the latest simplest solution - no need to change anything, just add three lines of CSS rules to your container of the div where you wish to center at. I love Flex Box #LoveFlexBox

_x000D_
_x000D_
.main {_x000D_
  /* I changed height to 200px to make it easy to see the alignment. */_x000D_
  height: 200px;_x000D_
  vertical-align: middle;_x000D_
  border: 1px solid #000000;_x000D_
  padding: 2px;_x000D_
  _x000D_
  /* Just add the following three rules to the container of which you want to center at. */_x000D_
  display: flex;_x000D_
  flex-direction: column;_x000D_
  justify-content: center;_x000D_
  /* This is true vertical center, no math needed. */_x000D_
}_x000D_
.inner {_x000D_
  border: 1px solid #000000;_x000D_
}_x000D_
.second {_x000D_
  border: 1px solid #000000;_x000D_
}
_x000D_
<div class="main">_x000D_
  <div class="inner">This box should be centered in the larger box_x000D_
    <div class="second">Another box in here</div>_x000D_
  </div>_x000D_
  <div class="inner">This box should be centered in the larger box_x000D_
    <div class="second">Another box in here</div>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Bonus

the justify-content value can be set to the following few options:

  • flex-start, which will align the child div to where the flex flow starts in its parent container. In this case, it will stay on top.

  • center, which will align the child div to the center of its parent container. This is really neat, because you don't need to add an additional div to wrap around all children to put the wrapper in a parent container to center the children. Because of that, this is the true vertical center (in the column flex-direction. similarly, if you change the flow-direction to row, it will become horizontally centered.

  • flex-end, which will align the child div to where the flex flow ends in its parent container. In this case, it will move to bottom.

  • space-between, which will spread all children from the beginning of the flow to the end of the flow. If the demo, I added another child div, to show they are spread out.

  • space-around, similar to space-between, but with half of the space in the beginning and end of the flow.


Since vertical-align works as expected on a td, you could put a single celled table in the div to align its content.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Clunky, but works as far as I can tell. It might not have the drawbacks of the other workarounds.


Try this, works for me very well:

/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;

/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;

/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;

/* W3C */
display:box;
box-pack:center;
box-align:center;

Setting the line-height to the same height as it's containing div will also work

DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}

Using CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

.outer {
  display : flex;
  align-items : center;
}

use "justify-content: center;" to align elements horizontally

Note: This might not work in old IE's