为啥图像垂直居中,`line-height` 位于它们应该在的位置下方 2 个像素?

Posted

技术标签:

【中文标题】为啥图像垂直居中,`line-height` 位于它们应该在的位置下方 2 个像素?【英文标题】:Why are images centered vertically with `line-height` positioned 2 pixels below where they should be?为什么图像垂直居中,`line-height` 位于它们应该在的位置下方 2 个像素? 【发布时间】:2012-08-28 21:24:21 【问题描述】:

短篇小说:

jsfiddle here。这种行为在 Chrome 21、Firefox 15 和 IE9 中一直是错误的,这让我觉得我对 CSS 规范有些误解。

更长的故事:

我想使用 line-height 垂直居中图像。我已将图像容器的高度设置为等于行高,我已重置所有元素的边距、填充和边框,但图像比应有的位置低 2 个像素。无论图像小于容器还是大于容器都会发生这种情况(在这种情况下,我使用max-width: 100; max-height: 100% 来缩小它的大小)。

在这两种情况下,图像的像素数都是偶数。我不会太在意比容器小的图像,但对于更大的图像,容器背景的 2 像素线会在图像顶部渗出。

<!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>

【问题讨论】:

你尝试过没有“vertical-align: middle”规则的各种组合吗? 内联图像的常见问题,如果规范中有关于它的内容,我从不关心查找。通常我可以通过将图像设置为显示块并设置边距:0 auto;来绕过这个问题。但是这种方法不允许您进行流体垂直对齐(仅当您知道高度测量时)。 jsfiddle.net/8UaUQ 【参考方案1】:

如果你在这个 div 中也有文本,你可以使用这个属性:

.img-wrapper-center 
    display: flex;
    justify-content: center;

这里是小提琴:https://jsfiddle.net/rjurado/yvanL4k1/2/

【讨论】:

【参考方案2】:

您必须为容器 div 元素设置零 font-size。 因为图像显示为内联元素,所以它们受容器 div 中的文本影响。零font-size 解决了这个问题:

.img-wrapper-center

    font-size:0;

这里是小提琴:http://jsfiddle.net/bZBsR/

【讨论】:

以上是关于为啥图像垂直居中,`line-height` 位于它们应该在的位置下方 2 个像素?的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp UIButton类别用于垂直居中标题标签和图像。文本标签位于图像下方。

c_cpp UIButton类别用于垂直居中标题标签和图像。文本标签位于图像下方。

line-height 垂直居中

CSS3垂直居中总结

为什么只设置line-height就可以实现文本垂直居中效果

垂直居中小记 line-height table vertical-align:middle