Sunday, March 27, 2011

How do I vertically align text next to an image with CSS?

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.

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

    sam : 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.
  • Here's an interesting article:

    Understanding vertical-align

    sam : vertical-align:middle on the image does the trick.
    Michael Haren : that's a cool resource, thanks Fistandantilus
  • 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.

  • 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

    sam : And if the image height is dynamic? I'm screwed :( PS, just because documentation exists for CSS doesn't make it annoying or unintuitive.
    strager : 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.
    Michael Haren : 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.
  • 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.
    sam : Thank you sir... I thought I tried every permutation of "vertical-align" on the elements but I skipped this one :)
    : Tested in IE 6 & 7. Works a treat.
  • 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

0 comments:

Post a Comment