Search code examples
cssvertical-alignment

Vertically align middle of image to full x-height of font


CSS has a vertical-align: middle property for inline elements, which vertically aligns the middle of the element to half of the x-height of the parent element's font. However, this often puts images a little lower than I want them. Is there a way to vertically align the middle of an arbitrary image to the full x-height of the parent element's font?

For instance, setting vertical-align: calc(1ex - 50%) on the image doesn't work because it takes 50% of the parent element's height rather than 50% of the image's height.

Actual output from vertical-align: middle using the image Image with line through middle:

img {
  vertical-align: middle;
}
<p>This is some text with an <img src="https://i.sstatic.net/fPdDaN6t.png"> image</p>

Image of output:

enter image description here

Desired output:

Image aligned to x-height of text


Solution

  • It seems that adding transform: translatey(-0.5ex); to the vertical-align: middle; does the trick to some degree:

    img {
      vertical-align: middle;
      transform: translatey(-0.5ex);
      width: 20px; /* unrelated */
    }
    
    body {
      font-size: 22px;
    }
    <span style="font-family: serif; word-spacing: -.5ch;">
    x <img height="10" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="40" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="80" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="120" src="https://i.sstatic.net/fPdDaN6t.png">
    x
    </span>
    
    <span style="font-family: Impact; word-spacing: -.3ch;">
    x <img height="10" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="40" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="80" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="120" src="https://i.sstatic.net/fPdDaN6t.png">
    x
    </span>
    <span style="font-family: monospace; word-spacing: -1ch;">
    x <img height="10" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="40" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="80" src="https://i.sstatic.net/fPdDaN6t.png">
    x <img height="120" src="https://i.sstatic.net/fPdDaN6t.png">
    x
    </span>

    Presumably, this workaround will fail miserably for fonts with disproportionally tall descenders and narrow cap height with resulting baseline shifted unusually high in the line box. (Cannot find a good example right now, maybe in CSS the x-height "band" is always centred after all (?))