280

The code:

<div 
  id="theMainDiv"
  style="
    border:solid 1px gray;
    cursor:text;
    width:400px;
    padding:0px;"
>
  <span 
    id="tag1_outer" 
    style="
      background:#e2e6f0;
      padding-right:4px;
      padding-left:4px;
      border:solid 1px #9daccc;
      font:normal 11px arial;
      color:#3c3c3c"
  >as</span>
</div>

As it renders now, the span is align the bottom-left corner of the div.

JGallardo
  • 11,074
  • 10
  • 82
  • 96
Babiker
  • 18,300
  • 28
  • 78
  • 125
  • Solution without lineheight and with flex is: id="theMainDiv" style=" border:solid 1px gray; cursor:text; width:400px; padding:0px; display:flex; align-content: middle;" – Sanid Sa Mar 22 '22 at 11:19

5 Answers5

215

See my article on understanding vertical alignment. There are multiple techniques to accomplish what you want at the end of the discussion.

(Super-short summary: either set the line-height of the child equal to the height of the container, or set positioning on the container and absolutely position the child at top:50% with margin-top:-YYYpx, YYY being half the known height of the child.)

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 10
    @Blender Heh, though therein references a third option: `display:table-cell; vertical-align:middle` (along with a `display:table-row` parent). :) But no, you can be sure that I would [never advocate using HTML table elements for layout](http://phrogz.net/CSS/WhyTablesAreBadForLayout.html). – Phrogz Dec 05 '10 at 04:19
  • what happens if you padding-top??? a fixed no based on height of the parent. i think your solution works even if the height is dynamic right. – kobe Dec 05 '10 at 04:30
  • 1
    So if you want to do this without a fixed height, there's no way to do it? – Ryan Lundy Mar 08 '12 at 20:52
  • 2
    @Kyralessa No, if you don't have a fixed height for the content there exist a couple techniques not yet listed in my page. For example, see: http://css-tricks.com/centering-in-the-unknown/ – Phrogz Mar 08 '12 at 21:37
  • 6
    @Phrogz - you should add the last option in http://css-tricks.com/centering-in-the-unknown/ to your answer. It's so clean and ie8+! – plainjimbo Sep 02 '12 at 02:31
  • @StevenLu Thanks for the motivation. 5 years ago I had not the experience with SO that I have now, and I too would downvote my answer as it is only a link to an external site. I will find time to put the various code answers into my answer. Hopefully "soon". – Phrogz Jun 26 '15 at 18:12
  • Yep, there are a lot of helpful articles out there by now that show many ways to get this job done. However, It's really a shame how complex every one of these approaches is. Flexbox offers a glimmer of hope, but is also incredibly complex. – Steven Lu Jun 26 '15 at 19:20
  • "Setting the line-height equal to that of container.." doesn't seem to work when the text on line is using different font sizes. e.g. In method 2 example in your article, I changed the text "is" to is and text was no longer appearing at center. This was exactly the case for which I was looking for a way to center and I chanced upon this question. – Nitesh Jul 26 '15 at 09:51
  • 7
    What if `YYY` is unknown?? – Shimmy Weitzhandler Nov 24 '15 at 12:58
206

At your parent DIV add

display:table;

and at your child element add

 display:table-cell;
 vertical-align:middle;
Otto Kanellis
  • 3,629
  • 1
  • 23
  • 24
  • 1
    This works, but is there an easy way to horizontally center the child element in the parent as well? Since the child's display isn't an inline-block anymore, the parent's "text-align: center;" css no longer works. – jnel899 Jun 20 '19 at 13:49
74

Quick answer for single line span

Make the child (in this case a span) the same line-height as the parent <div>'s height

<div class="parent">
  <span class="child">Yes mom, I did my homework lol</span>
</div>

You should then add the CSS rules

.parent { height: 20px; }
.child { line-height: 20px; vertical-align: middle; }



Or you can target it with a child selector

.parent { height: 20px; }
.parent > span { line-height: 20px; vertical-align: middle; }

Background on my own use of this

I ran into this similar issue where I needed to vertically center items in a mobile menu. I made the div and spans inside the same line height. Note that this is for a meteor project and therefore not using inline css ;)

HTML

<div class="international">        
  <span class="intlFlag">
    {{flag}}        
  </span>

  <span class="intlCurrent">
    {{country}}
  </span>

  <span class="intlButton">
    <i class="fa fa-globe"></i>
  </span> 
</div>

CSS (option for multiple spans in a div)

.international {
  height: 42px;
}

.international > span {
  line-height: 42px;
}

In this case if I just had one span I could have added the CSS rule directly to that span.

CSS (option for one specific span)

.intlFlag { line-height: 42px; }

Here is how it displayed for me

enter image description here

JGallardo
  • 11,074
  • 10
  • 82
  • 96
42

As in a similar question, use display: inline-block with a placeholder element to vertically center the span inside of a block element:

html, body, #container, #placeholder { height: 100%; }

#content, #placeholder { display:inline-block; vertical-align: middle; }
<!doctype html>
<html lang="en">
  <head>
  </head>

  <body>
    <div id="container">
      <span id="content">
        Content
      </span>
      <span id="placeholder"></span>
    </div>
  </body>
</html>

Vertical alignment is only applied to inline elements or table cells, so use it along with display:inline-block or display:table-cell with a display:table parent when vertically centering block elements.

References:

CSS Horizontal and Vertical Centering

Community
  • 1
  • 1
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
1

To the parent div add a height say 50px. In the child span, add the line-height: 50px; Now the text in the span will be vertically center. This worked for me.

DTS
  • 119
  • 1
  • 3