[html] Vertical align text in block element

I know vertical alignment is always asked about, but I don't seem to be able to find a solution for this particular example. I'd like the text centered within the element, not the element centered itself:

HTML:

<ul>
    <li><a href="">I would like this text centered vertically</a></li>
</ul>

CSS:

li a {
    width: 300px;
    height: 100px;
    margin: auto 0;
    display: block;
    background: red;
}

_x000D_
_x000D_
li a {_x000D_
    width: 300px;_x000D_
    height: 100px;_x000D_
    margin: auto 0;_x000D_
    display: block;_x000D_
    background: red;_x000D_
}
_x000D_
<ul>_x000D_
    <li><a href="">I would like this text centered vertically</a></li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_

Is there really no CSS3 property for this? I'd be willing to add a <span> in but I really don't want to add any more markup than that.

Thanks!

This question is related to html css

The answer is


li a {
width: 300px;
height: 100px;
display: table-cell;
vertical-align: middle;
margin: auto 0;
background: red;

}


Here's the general solution using just CSS, with two variations. The first centers vertically in the current line, the second centers within a block element.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
    <ul>
        <li>
            line one
        </li>
        <li>
            <span style="display: inline-block; vertical-align: middle">line two dot one
                <br />
                line two dot two</span>
        </li>
        <li>
            line three
        </li>
    </ul>
    <div style="height: 200px; line-height: 200px; border-style: solid;">
            <span style="display: inline-block; vertical-align: middle; line-height: normal;">line two dot one
                <br />
                line two dot two</span>
    </div>
</body>
</html>

As I understand it, vertical-align applies only to inline-block elements, e.g., <img>. You have to change an element's display attribute to inline-block for it to work. In the example, the line height expands to fit the span. If you want to use a containing element, such as a <div>, set the line-height attribute to be the same as the height. Warning, you will have to specify line-height: normal on the contained <span>, or it will inherit from the containing element.


Would using padding be OK for your needs?: http://jsfiddle.net/sm8jy/:

li {
    background: red;
    text-align:center;
}
li a {
    padding: 4em 0;
    display: block;
}

DO NOT USE THE 4th solution from top if you are using ag-grid. It will fix the issue for aligning the element in middle but it might break the thing in ag-grid (for me i was not able to select checkbox after some row). Problem is not with the solution or ag-grid but somehow the combination is not good.

DO NOT USE THIS SOLUTION FOR AG-GRID

li a {
    width: 300px;
    height: 100px;
    margin: auto 0;
    display: inline-block;
    vertical-align: middle;
    background: red;  
}

li a:after {
    content:"";
    display: inline-block;
    width: 1px solid transparent;
    height: 100%;
    vertical-align: middle;
}

You can also use inline-table alongside table-cell if you want to center your items vertically and horizontally. Below an example of using those display properties to make a menu:

_x000D_
_x000D_
.menu {_x000D_
  background-color: lightgrey;_x000D_
  height: 30px; /* calc(16px + 12px * 2) */_x000D_
}_x000D_
_x000D_
.menu-container {_x000D_
  margin: 0px;_x000D_
  padding: 0px;_x000D_
  padding-left: 10px;_x000D_
  padding-right: 10px;_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.menu-item {_x000D_
  list-style-type: none;_x000D_
  display: inline-table;_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.menu-item a {_x000D_
  display: table-cell;_x000D_
  vertical-align: middle;_x000D_
  padding-left: 2px;_x000D_
  padding-right: 2px;_x000D_
  text-decoration: none;_x000D_
  color: initial;_x000D_
}_x000D_
_x000D_
.text-upper {_x000D_
  text-transform: uppercase;_x000D_
}_x000D_
_x000D_
.text-bold {_x000D_
  font-weight: bold;_x000D_
}
_x000D_
<header>_x000D_
  <nav class="menu">_x000D_
    <ul class="menu-container">_x000D_
      <li class="menu-item text-upper text-bold"><a href="javascript:;">StackOverflow</a></li>_x000D_
      <li class="menu-item"><a href="javascript:;">Getting started</a></li>_x000D_
      <li class="menu-item"><a href="javascript:;">Tags</a></li>_x000D_
    </ul>_x000D_
  </nav>_x000D_
</header>
_x000D_
_x000D_
_x000D_

It works by setting display: inline-table; to all the <li>, and then applying display: table-cell; and vertical-align: middle; to the children <a>. This gives us the power of <table> tag without using it.

This solution is useful if you do not know the height of your element.

The compatibilty is very good (relative to caniuse.com), with Internet Explorer >= 8.


You can also try

a {
  height:100px;
  line-height:100px;
}

You can try the display:inline-block and :after.Like this:

HTML

<ul>
    <li><a href="">I would like this text centered vertically</a></li>
</ul>

CSS

li a {
    width: 300px;
    height: 100px;
    margin: auto 0;
    display: inline-block;
    vertical-align: middle;
    background: red;  
}
li a:after {
  content:"";
  display: inline-block;
  width: 1px solid transparent;
  height: 100%;
  vertical-align: middle;
}

Please view the demo.


with thanks to Vlad's answer for inspiration; tested & working on IE11, FF49, Opera40, Chrome53

li > a {
  height: 100px;
  width: 300px;
  display: table-cell;
  text-align: center; /* H align */
  vertical-align: middle;
}

centers in all directions nicely even with text wrapping, line breaks, images, etc.

I got fancy and made a snippet

_x000D_
_x000D_
li > a {_x000D_
  height: 100px;_x000D_
  width: 300px;_x000D_
  display: table-cell;_x000D_
  /*H align*/_x000D_
  text-align: center;_x000D_
  /*V align*/_x000D_
  vertical-align: middle;_x000D_
}_x000D_
a.thin {_x000D_
  width: 40px;_x000D_
}_x000D_
a.break {_x000D_
  /*force text wrap, otherwise `width` is treated as `min-width` when encountering a long word*/_x000D_
  word-break: break-all;_x000D_
}_x000D_
/*more css so you can see this easier*/_x000D_
_x000D_
li {_x000D_
  display: inline-block;_x000D_
}_x000D_
li > a {_x000D_
  padding: 10px;_x000D_
  margin: 30px;_x000D_
  background: aliceblue;_x000D_
}_x000D_
li > a:hover {_x000D_
  padding: 10px;_x000D_
  margin: 30px;_x000D_
  background: aqua;_x000D_
}
_x000D_
<li><a href="">My menu item</a>_x000D_
</li>_x000D_
<li><a href="">My menu <br> break item</a>_x000D_
</li>_x000D_
<li><a href="">My menu item that is really long and unweildly</a>_x000D_
</li>_x000D_
<li><a href="" class="thin">Good<br>Menu<br>Item</a>_x000D_
</li>_x000D_
<li><a href="" class="thin">Fantastically Menu Item</a>_x000D_
</li>_x000D_
<li><a href="" class="thin break">Fantastically Menu Item</a>_x000D_
</li>_x000D_
<br>_x000D_
note: if using "break-all" need to also use "&lt;br>" or suffer the consequences
_x000D_
_x000D_
_x000D_