338

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:

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

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

TylerH
  • 20,799
  • 66
  • 75
  • 101
Brad
  • 10,015
  • 17
  • 54
  • 77

19 Answers19

251

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

Dinesh Kumar
  • 2,838
  • 1
  • 16
  • 18
231

This seems to be the best way - some time has passed since my original post and this is what should be done now:

.main {
  display: table;
  
  /* optional css start */
  height: 90px;
  width: 90px;
  /* optional css end */
}
        
.inner {
  border: 1px solid #000000;
  display: table-cell;
  vertical-align: middle;
}
<div class="main">
  <div class="inner"> This </div>
</div>
ethry
  • 731
  • 6
  • 17
Charles D Pantoga
  • 4,307
  • 1
  • 15
  • 14
  • 4
    So how does someone do what the OP wants to do? – Ryan Mortensen May 18 '13 at 22:30
  • Any ideas on variable line paragraphs? ie. if there is no way of knowing whether it will be one or two lines. Would I need to user jQuery then? – The Thirsty Ape Feb 11 '14 at 21:54
  • What if the height must be dynamic, what is the solution? – Murhaf Sousli Jan 25 '15 at 14:40
  • shouldn't be the accepted answer, relies on knowing height of '.inner', so not exactly what the OP was asking for and some much better answers below see @timbergus or Tim Perkins' answers way down near the bottom. – mike-source May 14 '16 at 15:56
  • @mike-source knowing the height of inner is 100% possible even if the height is dynamic since a little bit of javascript can figure that out and dynamically change the CSS rule for that DOM object. – Charles D Pantoga May 24 '16 at 11:39
  • @CharlesAddis Yes it's possible, and I would think most front-end devs would be aware of that option. The point is there are better answers which are pure CSS. It's just much tidier and means all your styling is in one place, instead of having to rely on a piece of javascript. How you attach and execute that JS will need to be thought about, and there are still a minority of people who will have JS turned off for security reasons. Flexbox is the best bet for modern browsers, or one of the other answers I mentioned for something that will work in old browsers. All of them are pure CSS. – mike-source May 24 '16 at 15:03
  • This doesn't work. It's only centered because of the even padding. Set a fixed height and see... – Sauce Oct 17 '16 at 21:03
  • 1
    @Sauce works fine for me when setting a fixed height. If you noticed, the jsfiddle that's attached here is not the current solution provided. My guess is you clicked the JSFiddle, rather than actually using the code. – Charles D Pantoga Oct 17 '16 at 21:31
141

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;
Mahendra Liya
  • 12,912
  • 14
  • 88
  • 114
  • 5
    excellent answer, this has given me a fully working solution that hasn't caused other knock-on issues (an app using jquerymobile + phonegap and all the other solutions led to css & div sizing issues). Just to point out that these parameters have to be added to a CSS block specific to the elements to be centred/middled, eg: `#element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}` - note the height is important to ensure the span inherits the full height of its container (probably a div) otherwise you still won't get vertical centering! – Andy Lorenz May 02 '14 at 22:27
  • BTW, you can write standard flexbox code without browser prefixes and then get browser prefixed with autoprefixer https://github.com/postcss/autoprefixer or via online demo http://simevidas.jsbin.com/gufoko/quiet – starikovs Jan 22 '15 at 13:46
  • 2
    invalid property value `box` in `display` – Joaquinglezsantos Feb 17 '16 at 13:55
  • Also, @user1782556's answer works better when the outer box has padding. – iautomation Feb 23 '16 at 17:39
  • in 2023, this is equal to `display:flex; align-items: center` in modern CSS syntax. And this is still a work-arround when text in div is not vertical aligned. – Radian Jheng Feb 16 '23 at 03:42
35

Setting the line-height to the same height as it's containing div will align content in the middle vertically;

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

.inner {
    line-height:72px;
    border: 1px solid #000000;
}
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
Kevin Lynch
  • 24,427
  • 3
  • 36
  • 37
29

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.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>
kornieff
  • 2,389
  • 19
  • 29
  • This is actually the most well done solution, especially since most projects I've seen so far need IE9 compatibility – Jabberwocky Nov 29 '18 at 09:53
  • I like this solution, but it shrinks my content by 50%? How do I avoid that? – dko Feb 07 '22 at 15:55
  • **EDIT:** Found my solution, I used the solution above and added `width: 80%` to fit my image content into the container. – dko Feb 07 '22 at 16:05
27

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+

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

Fiddle

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Tim Perkins
  • 2,339
  • 3
  • 20
  • 13
  • 1
    This is probably the simplest way... all other answers on this page are unnecessarily clunky/hacky OR not supported in older browsers OR rely on knowing the height of the inner element. You don't actually need the `line-height: normal;` and `display:inline;` works too. The bonus of this method is it doesn't interfere with `text-align:center;`, which using `display: table-cell;` can create issues with. Quite often we want to align horizontally as well as vertically. See this edited fiddle: http://jsfiddle.net/br090prs/36/ – mike-source May 14 '16 at 15:40
  • 2
    @mike-source the reason to use `line-height: normal` and `display: inline-block` is so that the inner text will wrap properly. If you're sure that the text in the inner div will never wrap then these properties won't be necessary. – Tim Perkins May 17 '16 at 20:10
  • Ever since [Microsoft ended support for old versions of IE](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support) I have used flexbox for this sort of thing (as @user1782556 suggested). My original answer is the way to go if you still need to support IE 10 or older. – Tim Perkins May 17 '16 at 20:26
  • 100% agree, but I wouldn't personally go for flex box just yet, only 76% of browsers fully support it as of May 2016 (94% if you include partial support), see: http://caniuse.com/#search=flexible%20box. It is getting very close to being the most sensible option though, depending on your user base. – mike-source May 19 '16 at 15:51
  • 2
    `vertical-align: middle` has (almost) no effect here. It is the line-height that positions the `.inner` in the middle. – Devs love ZenUML Mar 11 '21 at 06:27
13

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

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

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;
        align-items: center; // To center align it horizontally as well
}

You can also use CSS Grids ( a two-dimensional grid-based layout system).

.main {
  display: grid;
  justify-content: center;
  align-content: center;
}

Below is a Shorthand approach but browser support is still low - https://caniuse.com/?search=place-items.

    .main {
      display: grid; // flex  -  works for both
      place-items: center;
    }

And you are good to go!

king
  • 273
  • 5
  • 8
8

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.

Brijesh Patel
  • 91
  • 1
  • 3
7

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

Timbergus
  • 3,167
  • 2
  • 36
  • 35
5

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;
}
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Dory Zidon
  • 10,497
  • 2
  • 25
  • 39
  • 3
    I think that if you define the height of the #inner block it invalidates the concept of proper vertical centering. The OPS was asking to make it automatic, so I would imagine that means the height of the inner box is not known at conception time. – Alexis Wilke Mar 12 '14 at 02:29
4

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!

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
RizonBarns
  • 611
  • 5
  • 6
4

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

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

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.

Downhillski
  • 2,555
  • 2
  • 27
  • 39
  • Perfect solution. The incompatible browsers can take the content unaligned and the user must deal with it or upgrade his/her browser. – twicejr Nov 28 '16 at 09:57
0

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.

Smig
  • 683
  • 6
  • 17
0

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>
0

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;
}
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Toki
  • 268
  • 3
  • 10
0

set below CSS

 /*Parent*/
 display: table;

/*immediate child*/
display: table-cell;
vertical-align: middle;

~Rahul Daksh

Rahul Daksh
  • 212
  • 1
  • 7
0

THIS IS THE ANSWER:

vertical-align aligns elements relative to the dimensions of the line the element appears in.

reference: https://christopheraue.net/design/why-vertical-align-is-not-working

gamolly
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 07 '22 at 02:38
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/33332377) – Lord-JulianXLII Dec 08 '22 at 14:36
0

The question was "WHY?".

The answer: vertical-align only works in certain conditions in the "display: table-cell;"

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191