How to centre text vertically reative to image (in a table)

I have a table like the one in the illustration and I want to find a way to centre text vertically in the first column so that it is always centred relative to the left icon:

The first row is easy when the text takes up only one line - I simply set vertical-align: middle on the <td> and <img>. However, I when the text overflows to the second line it goes down below the image - not what I want. I want it to be centred vertically like in the illustration (I made the second row as it should be in photoshop). How can I do it with CSS? I also tried float: left, but it failed as well. I know I could place the icon and the text into another table but that seems ugly.

Of course, this is a table so the width and height of the first column can be variable depending on how much content there is in other rows and cells so I don’t want to set any fixed dimensions. And I’d like it to work in IE8+.

you need to wrap your text in a SPAN, and give THAT display:inline-block; that way the text(actually the SPAN) will be treated as a unit

Okay, I wrapped the text in a SPAN with inline-block but the SPAN sits next to the image only when the text is short. When it is longer than one line then the whole SPAN goes under the image.

Can you post a live example, or some code we can play with?

Try this:

image is in a <span>, text is in a <p>; both tags are set to {display:table-cell}.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!--
http://www.sitepoint.com/forums/showthread.php?927171-How-to-centre-text-vertically-reative-to-image-%28in-a-table%29
Thread: How to centre text vertically reative to image (in a table)
2012.11.26 18:18
Lemon Juice
-->
<head>
    <title>Instant Columns</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <style type="text/css">

td {
    border:1px solid #faf;   /* temp layout testing */
    width:500px;             /* probably already defined */
    height:200px;            /* if needed */
}
span {
    display:table-cell;
    vertical-align:middle;
    background-color:#ccc;   /* temp layout testing */
    margin:4px;
}
img {
    padding:4px;
}
p {
    display:table-cell;
    vertical-align:middle;
    background-color:#fcc;   /* temp layout testing */
    padding:8px;
}

    </style>
</head>
<body>

<table>
<tr>
    <td>
        <span><img src="images/mt-rainier.jpg"></span>
        <p>This is a line of text beside the image in the table cell.</p>
    </td>
</tr>
</table>

</body>
</html>


Tested in FF17 and IE8

You can have a table-cell element inside a table-cell?

Might work today, though I know it would not have worked a few years ago when browsers like FF and Safari would throw hissie fits if you didn’t have this level of layers:
display: table grandparent
display: table-row parent
display: table-cell children

…and now looking at it, since images are inlines, the span could probably be removed and its styles given directly to the img.

What ronpat is doing by making the inlines inside the td also table-cell is letting the td act more like a table-row and now the two children inside (span and p) will want to equalise their heights like table-cells tend to do.

I’m trying to find the old demo of Paul’s which had a text string next to an image, but I think indeed that one only worked if the text couldn’t wrap, because it centered using line-height.

When it is longer than one line then the whole SPAN goes under the image.

It wants to not wrap. Though you don’t want to set dimensions on the td or the table, depending on your content you might be able to get away with setting a max-width on your text element (which would force a wrap, hopefully before the text string is long enough to drop under the image).

ronpat, thanks, your code does exactly what I want - I was worried about the fixed dimensions you set on the cell but when I removed them it still works! Here is the live demo based on your code, stripped of declarations I found unnecessary.

I also remember this issue a few years ago but all current browsers have no problem with this. Hopefully, it’s been fixed for good.

I tried removing the span and style the img but for some reason it didn’t work - the text in <p> jumped to the next line. I don’t understand why the <span> is essential here, it would be ideal to get rid of it but if it has to stay then fine.

Hi, poes. Those images actually have to be inside a container. Doesn’t matter if <span> or <div>. But the styles won’t work if applied to the image. I’m impressed, too.

Thanks for the feedback, Lemon Juice. The css table family behaviors have gradually improved over the years. It’s nice to be able to take advantage of table-cell behavor without having to use an entire table set-up. Same for table. Worth the wait. :slight_smile: