views:

13043

answers:

6

Why won't "vertical-align: middle" work? And yet, "vertical-align: top" does work.

<div>
   <img style="width:30px;height:30px">
   <span style="vertical-align:middle">Doesn't work.</span>
</div>

CSS is so annoying.

+1  A: 

Because you have to set the line-height to the height of the div for this to work

Ikke
And yet, doing this in tables would be achieved with "vertical-align: center". CSS blows.
sam
I tried setting line-height to 30px and it still doesn't work.
sam
+4  A: 

Here's an interesting article:

Understanding vertical-align

Phaedrus
vertical-align:middle on the image does the trick.
sam
that's a cool resource, thanks Fistandantilus
Michael Haren
A: 

It is frustrating, the only way (in general) to make something vertically align in the middle is using tables. Otherwise you have to get tricky.

tkotitan
+1  A: 

You probably want this:

<div>
   <img style="width:30px; height:30px;">
   <span style="vertical-align:50%; line-height:30px;">Didn't work.</span>
</div>

As others have suggested, try vertical-align on the image:

<div>
   <img style="width:30px; height:30px; vertical-align:middle;">
   <span>Didn't work.</span>
</div>

CSS isn't annoying. You just don't read the documentation. ;P

strager
And if the image height is dynamic? I'm screwed :( PS, just because documentation exists for CSS doesn't make it annoying or unintuitive.
sam
Do you mean unannoying and intuitive? You didn't specify if he image's height is dynamic at all in your question, so I assumed the fixed height was what you were going to stick with.
strager
I'm with sam on this one. I assumed that items ought to be centered with whatever the img height turned out to be. I think we could all stand to cool down a bit though.
Michael Haren
+24  A: 

Actually, in this case it's quite simple: apply the vertical align to the image. Since it's all in one line, it's really the image you want aligned, not the text.

<!-- moved "vertical-align:middle" style from span to img -->
<div>
   <img style="width:30px;height:60px;vertical-align:middle">
   <span style="">Works.</span>
</div>

Tested in FF3.

Michael Haren
btw: I completely agree that CSS layout can be a nightmare. It makes a lot of things much easier, but some things are difficult.
Michael Haren
Thank you sir... I thought I tried every permutation of "vertical-align" on the elements but I skipped this one :)
sam
+4  A: 

As with most shortcomings of CSS in the wild, this is Microsoft's fault for taking eleven years to support it. Here's some simple techniques for vertical-align:

One-line vertical-align:middle

This one is easy: set the line-height of the text element to equal that of the container

<div>
  <img style="width:30px; height:30px;">
  <span style="line-height:30px;">Doesn't work.</span>
</div>

Multiple-lines vertical-align:bottom

Absolutely position an inner div relative to it's container

<div style="position:relative;width:30px;height:60px;">
  <div style="position:absolute;bottom:0">This is positioned on the bottom</div>
</div>

Multiple-lines vertical-align:middle

This one is a little tricky. The correct CSS way is to do this:

<div style="display:table;width:30px;height:60px;">
  <div style="display:table-cell;height:30px;">Doesn't work in IE!</div>
</div>

I order to get this to work correctly across the board, you'll have to hack the CSS a bit. Luckily, there is an IE bug that works in our favor. Setting top:50% on the container and top:-50% on the inner div, you can acheive the same result. We can combine the two using another feature IE doesn't support: advanced CSS selectors.

<style type="text/css">
  #container {
    width: 30px;
    height: 60px;
    position: relative;
  }
  #wrapper > #container {
    display: table;
    position: static;
  }
  #container div {
    position: absolute;
    top: 50%;
  }
  #container div div {
    position: relative;
    top: -50%;
  }
  #container > div {
    display: table-cell;
    vertical-align: middle;
    position: static;
  }
</style>

<div id="wrapper">
  <div id="container">
    <div><div><p>Works in everything!</p></div></div>
  </div>
</div>

Isn't the standard way so much nicer?

Friends don't let friends use Internet Explorer

Adam Lassek