27

What's the best way to center icons on a line when the images are smaller than the line height?

For example (styles inline for easier reading):

<div style="line-height: 20px">
  <img style="width: 12px; height: 12px;"/>
  Blah blah blah
</div>

Here's a jsFiddle example. This example also shows why vertical-align: middle does not work.

I want the img to be centered against the text of the div. That is, even if the text wrapped to multiple lines, the image would be centered against a single line. Ideally, the solution would not involve setting margings/paddings on the image and would work even if I didn't know the line-height.

Things I've read:

How do I vertically align text next to an image with CSS? (deals with case where image is larger, doesn't seem to apply here)

Understanding vertical-align

Community
  • 1
  • 1
Jeremy Kauffman
  • 10,293
  • 5
  • 42
  • 52
  • 2
    What's wrong with the solution specified in the links you're referring to? Using `` should work equally well when the image is smaller than the line-height. – Pär Wieslander Jun 15 '10 at 18:35
  • I might be missing something here, but what you have seems to vertically align as it is: `http://jsfiddle.net/JrFkE/` – edl Jun 15 '10 at 19:01
  • I added a fiddle that shows the issues with both of these approaches. – Jeremy Kauffman Jun 15 '10 at 19:22

3 Answers3

32

The cause of your problem is that the image is vertically centered relative to the x-height of the surrounding text. This can be seen quite clearly on an enlarged screenshot where the baseline and mean line of the surrounding text is included:

illustration of a vertically aligned image compared to the surrounding text's baseline and mean line

The image is aligned similarly no matter which font size or line height you use. So, in a typographical sense, the image is actually correctly vertically aligned. However, if you'd like to adjust the alignment so that the center of the image is closer to the mean line, simply move it a bit upwards using margin-bottom:

img.icon {
    margin-bottom: 0.25em;
}

The value of 0.25 em is rather arbitrarily chosen, based on what looked good when I tried it out. Adjust freely according to taste.

Here is a comparison before and after the margin-adjustment, with different font sizes.

Pär Wieslander
  • 28,374
  • 7
  • 55
  • 54
  • +1 I have always been stuck in this problem (inline images with text). That's a real solution. Thanx @Wieslander – shashwat Mar 25 '13 at 08:03
  • supplementary: img should vertical-align: bottom, and mergin-bottom: (line-height - image height) / 2 – linjunhalida Dec 22 '13 at 09:18
  • an answer that is "adjust this value until it looks centered" is not an answer. You're just manually positioning the image at that point and it will fail anytime anyone changes the style – gman Nov 19 '20 at 12:24
4

Why don't you set the image as background of the div element? I.e.:

<div style="line-height: 20px; background: url(path/image.gif) 5px 5px; no-repeat; padding-left: 40px;">
  Blah blah blah
</div>

This will position the image on the top left. At least that's how I would do.

Regards

Nik Chankov
  • 6,049
  • 1
  • 20
  • 30
  • 1
    Not a bad idea, but in this case the images are actually sprites (e.g. something like ) rather than img tags, so it won't work. – Jeremy Kauffman Jun 15 '10 at 18:59
  • @jeremy: Then why do you use an `img` tag in your question? – jeroen Jun 15 '10 at 20:32
  • Simplification. This solution also requires manually setting the distances, which I was hoping to avoid. If I change the text size or line height, I need to readjust the image position. – Jeremy Kauffman Jun 15 '10 at 20:59
  • @JeremyKauffman, the answer you marked has the same issue. It's "manually setting distances" – gman Nov 19 '20 at 12:25
3

Try to make parents container display: table and display: table-cell. After that vertical-align: middle should work in "table way".

vtambourine
  • 2,109
  • 3
  • 18
  • 27