730

The code below (also available as a demo on JS Fiddle) does not position the text in the middle, as I ideally would like it to. I cannot find any way to vertically centre text in a div, even using the margin-top attribute. How can I do this?

<div id="column-content">
    <img src="http://i.stack.imgur.com/12qzO.png">
    <strong>1234</strong>
    yet another text content that should be centered vertically
</div>
#column-content {
    display: inline-block;
    border: 1px solid red;
    position:relative;
}
    
#column-content strong {
    color: #592102;
    font-size: 18px;
}

img {
    margin-top:-7px;
    vertical-align: middle;        
}
Cyclone
  • 13,241
  • 22
  • 76
  • 112
  • http://stackoverflow.com/questions/5703552/css-center-text-horizontal-and-vertical-inside-a-div-block/25799339#25799339 – Josh Crozier Jan 17 '15 at 21:28

10 Answers10

708

Andres Ilich has it right. Just in case someone misses his comment...

A.) If you only have one line of text:

div
{
  height: 200px;
  line-height: 200px; /* <-- this is what you must define */
}
<div>vertically centered text</div>

B.) If you have multiple lines of text:

div
{
  height: 200px;
  line-height: 200px;
}

span
{
  display: inline-block;
  vertical-align: middle;
  line-height: 18px; /* <-- adjust this */
}
<div><span>vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text vertically centered text</span></div>
Krisztián Balla
  • 15,886
  • 11
  • 58
  • 69
475

Create a container for your text content, a span perhaps.

#column-content {
  display: inline-block;
}
img {
  vertical-align: middle;
}
span {
  display: inline-block;
  vertical-align: middle;
}

/* for visual purposes */
#column-content {
  border: 1px solid red;
  position: relative;
}
<div id="column-content">

  <img src="http://i.imgur.com/WxW4B.png">
  <span><strong>1234</strong>
    yet another text content that should be centered vertically</span>
</div>

JSFiddle

Carrie Kendall
  • 10,761
  • 5
  • 57
  • 79
Andres Ilich
  • 73,673
  • 21
  • 152
  • 136
  • 63
    Can you explain why, when a `height` property is specified for either the `span` or the span's parent element, the `vertical-align` property does not work? Using your demo specifically, I added a `height` property to the parent element to see if the `span` would still vertically align itself, but it doesn't. – Josh Apr 09 '12 at 15:31
  • 137
    @Josh that is due to `line-height`. If you add `height` to an element where exactly does the text inside of it lie? That is, if you have a block of text that is `font-size: 10px` (a theoretical `height:10px`) inside a container that is `60px` where exactly is the text going to end up? Most surely at the top of the container, because the text can only position itself where the text flows, inside a `height:10px` space. But you can overcome that by using a `line-height` value the same height as the container, this way the text will take in the `vertical-align` property and align itself properly. – Andres Ilich Apr 09 '12 at 15:56
  • 9
    @Josh demo: http://jsfiddle.net/9Y7Cm/37/ .. added a height of 100px to the container and also a line-height of 100px to the span tag. – Andres Ilich Apr 09 '12 at 15:57
  • 2
    This does not work with position fixed. – Ian S Mar 03 '14 at 19:16
  • I'm affraid it's not working: http://jsfiddle.net/jA53e/ – Alexandre Mélard Mar 21 '14 at 16:12
  • 2
    This only reason that jsfiddle demo "works" is the img has `vertical-align: middle;` set. Set a fixed height on the container and it does not center vertically: http://jsfiddle.net/9Y7Cm/5/ – Costa Nov 27 '14 at 01:21
  • I thought `vertical-align` doesn't work on `inline-block` elements. –  Sep 06 '17 at 06:36
  • It seems not working in chrome. – QMaster Feb 01 '19 at 17:28
  • 1
    Why is this the accepted answer ? just give #column-content a height of say 300px, and you will see it does not vertically align neither the image, nor the text. Due to the small height of your demo, it gives the illusion it is working. NON ANSWER. – joedotnot Dec 04 '19 at 07:15
  • Does this work with `position: fixed`? My span is the exact same, but the vertical align doesn't work with my div: `
    `
    – NobleUplift Apr 03 '20 at 17:16
  • The demo is not working. The text is aligned to the top of the image. – Arye Eidelman Jul 28 '20 at 22:11
266

Update April 10, 2016

Flexboxes should now be used to vertically (or even horizontally) align items.

body {
    height: 150px;
    border: 5px solid cyan; 
    font-size: 50px;
    
    display: flex;
    align-items: center; /* Vertical center alignment */
    justify-content: center; /* Horizontal center alignment */
}
Middle

A good guide to flexbox can be read on CSS Tricks. Thanks Ben (from comments) for pointing it out. I didn't have time to update.


A good guy named Mahendra posted a very working solution here.

The following class should make the element horizontally and vertically centered to its parent.

.absolute-center {

    /* 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;
}
vsync
  • 87,559
  • 45
  • 247
  • 317
Omar Tariq
  • 6,601
  • 9
  • 30
  • 54
  • 17
    Not anymore, the spec has changed and most of the above is now deprecated. [http://stackoverflow.com/questions/16280040/css3-flexbox-display-box-vs-flexbox-vs-flex] The logic of using flexbox however is sound, something like: ```display:flex; justify-content:center; align-items:center;``` – Ben Jul 14 '15 at 16:23
  • 1
    this is the only thing that worked for me – john ktejik Apr 28 '20 at 00:33
63

The accepted answer doesn't work for multi-line text.

I updated the JSfiddle to show CSS multiline text vertical align as explained here:

<div id="column-content">
    <div>yet another text content that should be centered vertically</div>
</div>

#column-content {
    border: 1px solid red;
    height: 200px;
    width: 100px;
}
div {
    display: table-cell;
    vertical-align:middle;
    text-align: center;
}

It also works with <br /> in "yet another..."

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Eduard Gamonal
  • 7,883
  • 5
  • 37
  • 42
  • 1
    i think the table cell should be on the wrapper, and secondly if wrapper has position absolute it stops working – luky Oct 08 '16 at 17:07
26

Try this:

HTML

<div><span>Text</span></div>

CSS

div {
    height: 100px;
}

span {
    height: 100px;
    display: table-cell;
    vertical-align: middle;
}
Petr Voborník
  • 1,072
  • 1
  • 12
  • 10
16

To make Omar's (or Mahendra's) solution even more universal, the block of code relative to Firefox should be replaced by the following:

/* Firefox */
display: flex;
justify-content: center;
align-items: center;

The problem with Omar's code, otherwise operative, arises when you want to center the box in the screen or in its immediate ancestor. This centering is done either by setting its position to

position: relative; or position:static; (not with position:absolute nor fixed).

And then margin: auto; or margin-right: auto; margin-left: auto;

Under this box center aligning environment, Omar's suggestion does not work. It doesn't work either in Internet Explorer 8 (yet 7.7% market share). So for Internet Explorer 8 (and other browsers), a workaround as seen in other above solutions should be considered.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
user2931920
  • 169
  • 1
  • 2
  • This worked for me thanks including when I use float:left: to create a row of buttons. The complexity of explaining why it works hints at the general difficulty with CSS: You can not achieve the simple effect of centering text inside a DIV with any single directive. You have to combine multiple attributes, and how they work in combination with other attributes is difficult to foresee without trying them out in different contexts including with different browsers. – Panu Logic Aug 05 '19 at 19:02
16

This is simply supposed to work:

#column-content {
        --------
    margin-top: auto;
    margin-bottom: auto;
}

I tried it on your demo.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ParPar
  • 6,660
  • 7
  • 40
  • 52
  • 3
    This should be the same as `margin:auto 0` where the first value ('auto') is for top and bottom margin and the second value (the 0) is for the left and right margin. – Joshua Apr 01 '16 at 04:24
  • 1
    You are right! but in this way it's more clear for beginners, and your comment makes it wiser. thanks! – ParPar Apr 03 '16 at 06:28
  • 3
    This works only with a parent element using either `display:flex` or `display:grid` or `display:inline-table` or `display:inline-grid`. Doesn't work in older browsers – Frondor Sep 10 '17 at 11:53
4

This is the simplest way to do it if you need multiple lines. Wrap you span'd text in another span and specify its height with line-height. The trick to multiple lines is resetting the inner span's line-height.

<span class="textvalignmiddle"><span>YOUR TEXT HERE</span></span>
.textvalignmiddle {
    line-height: /* Set height */;
}

.textvalignmiddle > span {
    display: inline-block;
    vertical-align: middle;
    line-height: 1em; /* Set line height back to normal */
}

DEMO

Of course the outer span could be a div or what have you.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Hashbrown
  • 8,877
  • 7
  • 57
  • 71
3

Add a vertical align to the CSS content #column-content strong too:

#column-content strong {
    ...
    vertical-align: middle;
}

Also see your updated example.

=== UPDATE ===

With a span around the other text and another vertical align:

HTML:

... <span>yet another text content that should be centered vertically</span> ...

CSS:

#column-content span {
    vertical-align: middle;
}

Also see the next example.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
scessor
  • 15,775
  • 4
  • 39
  • 53
-2

I know it’s totally stupid and you normally really shouldn’t use tables when not creating tables, but:

Table cells can align multiple lines of text vertically centered and even do this by default. So a solution which works quite fine could be something like this:

HTML:

<div class="box">
  <table class="textalignmiddle">
    <tr>
      <td>lorem ipsum ...</td>
    </tr>
  </table>
</div>

CSS (make the table item always fit to the box div):

.box {
  /* For example */
  height: 300px;
}

.textalignmiddle {
  width: 100%;
  height: 100%;
}

See here: http://www.cssdesk.com/LzpeV

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123