Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are images centered vertically with `line-height` positioned 2 pixels below where they should be?

Short story:

jsfiddle here. The behavior is consistently wrong in Chrome 21, Firefox 15 and IE9, which makes me think I'm misunderstanding something about the CSS spec.

Longer story:

I want to center an image vertically using line-height. I've set the height of the image container equal to the line-height, I've reset margins, paddings and borders for all elements, yet the image is 2 pixels below where it should be. This happens whether the image is smaller than the container, or larger than it (in which case I used max-width: 100; max-height: 100% to size it down).

The image has an even number of pixels in both cases. I wouldn't care that much for images smaller than the container, but for images that are larger, a 2-pixel line from the container background will bleed through at the top of the image.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Images centered vertically with line-height have center miscalculated by 2 pixels</title>

    <style type="text/css">
        * { margin: 0; padding: 0; border: 0px solid cyan; }  /* reset all margins, paddings and borders */
        html {
            font-size: 16px;
            line-height: normal;
        }
        body {
            line-height: 100%;
            background: gray;
        }
        .img-wrapper-center {
            width: 400px;
            height: 200px;  /* necessary, besides line-height, if images are taller than it */
            line-height: 200px;  /* must be equal to line-height */
            text-align: center;
            background: white;
        }
        .img-wrapper-center img {
            vertical-align: middle;
            /* Comment the two rules below. The first image will still be mis-aligned by two pixels, but the second will not. */
            max-width: 100%; max-height: 100%;  /* force scaling down large images */
        }

    </style>
</head>

<body>

    <div class="img-wrapper-center" id="div1">
        <img src="http://gravatar.com/avatar" id="img1"/>  <!-- 80x80 -->
    </div>

    <div class="img-wrapper-center" id="div2" style="background: green">
        <img src="http://www.w3.org/html/logo/img/class-header-semantics.jpg" id="img2" />  <!-- 495x370 -->
    </div>

    <p>
    Note how the second image is misaligned down by two pixels.
    The first one is mis-aligned the same way. Sizes and coordinates are below.
    </p>

    <script>
        document.writeln('div1 top: ' + document.getElementById('div1').offsetTop + '<br/>');
        document.writeln('image 1 height: ' + document.getElementById('img1').offsetHeight + '<br/>');
        document.writeln('div1 height: ' + (document.getElementById('div1').offsetHeight) + '<br/>');
        document.writeln('image 1 top should be at: ' + (document.getElementById('div1').offsetHeight - document.getElementById('img1').height) / 2 + '<br/>');
        document.writeln('image 1 top actually is at: ' + document.getElementById('img1').offsetTop + '<br/>');
        document.writeln('div2 top: ' + document.getElementById('div2').offsetTop + '<br/>');
        document.writeln('img2 top: ' + document.getElementById('img2').offsetTop + '<br/>');
    </script>

</body>
</html>
like image 295
Dan Dascalescu Avatar asked Sep 04 '12 08:09

Dan Dascalescu


People also ask

How are images positioned vertically CSS?

Method 1: Using the Position Property To center an image vertically, you can wrap it in a block element like a div and use a combination of the CSS position property, the left and top properties, and the transform property.

What does it mean to vertically align?

Vertical alignment is the state or act of lining items up, one above each other.

Does vertical-align work for images?

The vertical-align property can be used in two contexts: To vertically align an inline element's box inside its containing line box. For example, it could be used to vertically position an image in a line of text. To vertically align the content of a cell in a table.


1 Answers

You have to set zero font-size for container div elements. Because images are displayed as inline elements they are affected by text in container div. Zero font-size fixes this:

.img-wrapper-center
{
    font-size:0;
}

Here is fiddle: http://jsfiddle.net/bZBsR/

like image 77
keaukraine Avatar answered Nov 12 '22 21:11

keaukraine