80

I have a title that can have one or more lines.

How can I align the text vertically? If it was always one line I could just set the line-height to the container height.

I can do it using JavaScript, but I don't really like it, I'm searching for a pure CSS way.

Also if the container could expand with the lines it would be perfect, so I can always have the same padding on the top and bottom.

enter image description here

apaul
  • 16,092
  • 8
  • 47
  • 82
braindamage
  • 2,226
  • 4
  • 24
  • 33
  • In case the container height can change... then how about this? http://jsbin.com/idiqih/edit#preview – Joonas Feb 08 '12 at 11:55

8 Answers8

114

For this you can use display:table-cell property:

.inline {
  display: inline-block;
  margin: 1em;
}
.wrap {
  display: table;
  height:  100px;
  width:   160px;
  padding: 10px;
  border:  thin solid darkgray;
}
.wrap p {
  display:        table-cell;
  vertical-align: middle;
}
<div class="inline">
  <div class="wrap">
    <p>Example of single line.</p>
  </div>
</div>

<div class="inline">
  <div class="wrap">
    <p>To look best, text should really be centered inside.</p>
  </div>
</div>

But it works IE8 & above. Read this article for more info: CSS Tricks: Vertically Center Multi-Lined Text.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
sandeep
  • 91,313
  • 23
  • 137
  • 155
  • I wanted exactly the same thing, but also needed that the div should consume entire height available. This should help for it: http://stackoverflow.com/a/16837667/260665 – Raj Pawan Gumdal Apr 15 '15 at 09:50
  • If you don;t want the `.wrap` to have *magic numbers* for the `height` and `width`, you can set each of them to `100%`. Then apply the `width` and `height` to the parent of the `.wrap` elements. – Mr. Polywhirl Mar 31 '16 at 12:23
10

If you don't like the display:table trick (I know I don't) here's a solution without it:

.cen {
  min-height:5em; width:12em; background:red; margin:1em 0;
}
.cen p {
  display:inline-block; vertical-align:middle;
  margin:0 0 0 1em; width:10em;
}
.cen::after {
   display:inline-block; vertical-align:middle; line-height:5em;
   width:0; content:"\00A0"; overflow:hidden;
}

with HTML

<div class="cen">
 <p>Text in div 1</p>
</div>

This gives the div a height of 5em, unless the content is heigher, then it grows.
Live example here.

Edit: Oh, which browsers is this supposed to work on? IE8 won't cooperate.

(Later edit: updated CSS to handle issues in Chrome)

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • Cool technique. One issue I ran into was when the text in the box wrapped on its own (instead of with the `
    ` tags shown in the example) I wound up with a good deal of extra white space at the bottom of each element in Chrome. It seems like the pseudo element is wrapping onto a new line. Any idea how to mitigate that?
    – Dominic P Jun 24 '13 at 22:47
  • @DominicP You're right. Apparently the `::after` block thinks it does have a width (because of its content), so it won't fit after the `p`. Unfortunately it does need the content, or it would collapse altogether and it wouldn't work. But I'm not sure why it does this only with wrapping lines and not with single-line `p`s. – Mr Lister Jun 25 '13 at 05:39
  • Anyway, I updated the answer with the solution. The trick is to make the `p` less wide than the div, so there's room to the right of it for the zero-width `::after` block. Hope this helps! – Mr Lister Jun 25 '13 at 05:41
  • If accessibility is a concern, this is the correct answer. You shouldn't classify a `
    ` as a `table-item`, it will confuse the screen reader and, of course, the user.
    – Cthulhu Jun 05 '15 at 16:14
9

I really like this solution:

<div>
    <span style="display: inline-block; vertical-align: middle; height: --The height of your box here--"></span>
    <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here</span>
</div>

Feel free to use stylesheets, and 100% for the height...

Also might have to comment out spaces between the span tags, since these are inline-blocks

Credit goes to Hades. I got it from Here

<div style="outline:thin solid red;">
  <span style="display: inline-block; vertical-align: middle; height: 60px;"></span>
  <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here.</span>
</div>

<div style="outline:thin solid red;">
  <span style="display: inline-block; vertical-align: middle; height: 60px;"></span>
  <span style="display: inline-block; vertical-align: middle;">Put your multi-line content here. Put your multi-line content here. Put your multi-line content here. Put your multi-line content here. Put your multi-line content here.</span>
</div>

Note: This appears not to work with multiple line content.

Community
  • 1
  • 1
Rolf
  • 5,550
  • 5
  • 41
  • 61
4

Instead of using vertical-align: center and display: table-cell, you might want to take a look at the newer method called CSS display flex which is MUCH simpler

.box {
    width: 200px;
    height: 50px; 
    padding: 10px;
    margin-bottom: 20px;
    background-color: red;
    
    /* Only add these 2 lines */
    display: flex;
    align-items: center;
  }
<div class="box">Lorem ipsum dolor</div>
<div class="box">Lorem ipsum dolor sit amet ipsum dolor</div>
Hans Tiono
  • 808
  • 8
  • 8
3

If You want your text to be responsive, wrapping words from one to multiple lines as width is dynamically changing, mentioned above trick with inline-block helper (which have the best compability here) can be not sufficient, as .inlinehelper can push wrapping text down under itself.
Here's complete solution for such a simpel task:

HTML:

<div id="responsive_wrap">
    <span class="inlinehelper"><span id="content">        
</div>

CSS:

#responsive_wrap {   
   display: block;    
   height: 100%; //dimensions just for   
   width: 100%;  //example's sake
   white-space: nowrap;
}

#content {   
   display: inline-block;        
   white-space: initial;
}

.inlinehelper {
   height: 100%;    
   width: 0;
   vertical-align: middle;
   display: inline-block;
}

Notice the white-space:nowrap property, which prevents .inlinehelper and #content to wrap in relation to each other. white-space:initial on #content resets ability to wrap for span itself;

Another Option: More a matter of personal preference. You can use a pseudo element instead of .inlinehelper. Remove the .inlinehelper css rules and element and add this pseudo-element css selector:

#responsive_wrap:before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    height: 100%;
    width: 0px;
}

P.S.: I figured out that this is really old question too late, therefore let this answer be, maybe it will be helpfull for someone.

Habovh
  • 457
  • 8
  • 20
Max Yari
  • 3,617
  • 5
  • 32
  • 56
3

somthing like this

HTML

<div>
    <p>
       Lorem Ipsum is simply
    </p>
</div>

CSS

div {
   display: table;
}
p {
   display:table-cell;
   vertical-align: middle;
}
Community
  • 1
  • 1
Aram Mkrtchyan
  • 2,690
  • 4
  • 31
  • 47
1

Styling wise, a table would be the best way to layout your content (put the style tags in CSS):

<table style="border:1;collapse;width:300px;padding:5px;background-color:red;">
<tr>
    <td style="width:250px;vertical-align:middle;">Lorem ipsum dolor sit amet ipswum dolor</td>
    <td style="width:50px;vertical-align:top;color:white;">1 Line</td>
</tr>

Line count will require a JS script, have a look here:

http://www.webdeveloper.com/forum/archive/index.php/t-44333.html

Ryan Brodie
  • 6,554
  • 8
  • 40
  • 57
0

I like that kind of solution. I saw somewhere this trick in stackoverflow but do not remember where exactly. Very usefel! :)

ul {
background: #000; 
  padding-left: 0;
}
ul li {
  height: 130px;
  position: relative;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  border-bottom: 3px solid #F7F7F7;
}
ul li:last-of-type {
  border-bottom: none;
}
ul li:after {
  color: #333;
  position: absolute;
  right: 35px;
  font-size: 40px;
  content: ">";
  top: 50%;
  margin-top: -24px;
  color: #FFDA00;
  -webkit-transition: 0.25s all ease;
  transition: 0.25s all ease;
}
ul li a {
  font-size: 35px;
  font-family: Arial;
  color: #fff;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  padding-left: 40px;
  height: 100%;
  line-height: 38px;
  display: inline-block;
  width: 100%;
  text-align: left;
  text-decoration: none;
}
ul li a:before {
  display: inline-block;
  vertical-align: middle;
  content: " ";
  height: 100%;
}
ul li a span {
  display: inline-block;
  vertical-align: middle;
}
<ul>
 <li class="dn">
  <a href="kapec.ru.php"><span> Lorem ipsum 1 LINE</span></a>
  </li>
  <li>
   <a href="varianti.ru.php"><span>Lorem ipsum <br> 2 lines </span></a>
  </li>

 </ul>