在居中容器中居中的CSS图像会产生不可预测的结果

时间:2014-09-27 19:42:39

标签: html css centering

有一段时间我被困住了,我的中心背景图像在他们的容器中没有像素完美对齐。我甚至在同一个浏览器中得到了不同的结果,但是不同的窗口

最后我发现了正在发生的事情,但我还缺乏强大的跨浏览器解决方案。

案例:我在javascript中处理可折叠的树视图。一切正常,但在某些情况下,折叠/展开按钮向左偏离一个像素。

这些按钮的图像是用户可定义的,以及它们出现的容器的大小(宽度)。图像使用background-position: center center;绘制在这些容器的中心。现在有些情况下,图像无法正确地 在容器的中心(例如,将9px图像居中放在20px容器中,其中有1像素差异任何一边)。这应该没问题,只要我们对浏览器如何处理这一点有一致的行为。

但是在这里它变得凌乱:我已经根据浏览器视口在以margin:0 auto;为中心的包装器中实现了这个树视图。当视口居中和背景居中都不完全适合像素边界时,我会得到不同的结果。

这可能很难理解,所以我把问题简化为小提琴:http://jsfiddle.net/3y65wgu8/1/

CSS:

#wrapper1 {
    width:400px;
}
#inner1 { /* perfect center */
    margin:0 auto;
    width:200px; 
    height:50px;
}
#wrapper2 {
    width:399px;
}
#inner2 { /* 1px-offcenter */
    margin:0 auto;
    width:200px; 
    height:50px;
}
#container { /* image 1px-offcenter (9px centered in 12px container) */
    width:12px; 
    height:12px;
    background:url(data:image/gif;base64,R0lGODlhCQAJALMAANLNve/s58a7rd7Vznuatf////f39wAAALXD1vfz7+fj3tbTxsa6pdbPxt7b0sa2pSH5BAAAAAAALAAAAAAJAAkAAAQoEJFJiSw4l6mxmUYYJgp4nKczJUngKsOkOMOyNMAECALDPAJLhYKIAAA7) no-repeat center center #444;
}

HTML:

<div id="wrapper1">
    <div id="inner1">
        <div id="container"></div>
    </div>
</div>
<div id="wrapper2">
    <div id="inner2">
        <div id="container"></div>
    </div>
</div>

两个不同的包装器,以其内容为中心,包含两个相同的容器,其中一个小按钮被绘制为背景。 Chrome似乎是唯一能够一致地绘制对齐按钮的浏览器,但firefox和IE显示了我描述的问题。尝试调整浏览器窗口的大小,看到按钮从一侧反弹到另一侧。

我的问题是:如何在不失去按钮/容器/包装尺寸和样式的灵活性的情况下,至少获得相同的结果。

编辑:这是一张说明我的用例的图片:

Example

标记为蓝色的区域是容纳折叠按钮的容器。这个区域总是方形的,但大小可能不同。按钮可以是小于此容器的任何图像,并且直接放置在线条相交的顶部。图像上不应出现拉伸或缩放。在此示例中,按钮距离左侧太远。调整浏览器窗口的大小会使图像跳入和跳出正确的对齐方式,如上面的小提琴所描述的那样。

2 个答案:

答案 0 :(得分:1)

似乎没有办法解决这个问题,而不是在内部图像无法像素完美居中时调整图像容器的大小,以便在定位上保持一致的跨浏览器行为。因此,我需要在服务器端或客户端获取图像元数据。

服务器端(1): 使用getimagesizegetimagesizefromstring显然是要走的路。但后来我在我当前的用例中遇到了一个问题:使用AJAX渲染树,并且图像的相对URL与AJAX脚本的位置无关。

<强>问题: 因此,为了实现这一点,我要么必须传递URL和绝对路径(或者仅使用绝对路径,并通过从中删除$_SERVER['DOCUMENT_ROOT']来确定URL)。对于尝试实现此树模块的开发人员而言,这种方法似乎是违反直觉和限制的。所以我放弃了这个想法。

服务器端(2): 在设计时询问图像尺寸。简单明了,将责任放在实施者身上。

<强>问题: 不是很优雅,但它的工作原理:)。 (解决方案1)

<强>客户端: 我是隐藏的DIV中的两个图像,我从onload事件中获取图像的大小。如果通过此数据,容器内使用的图像偏离中心(image.width%2 != container.width%2image.height%2 != container.height%2),我会遍历这些容器,并将它们的宽度或高度调整为一个像素。

<强>问题: 我不喜欢将隐藏元素与触发器一起使用的唯一目的是解决这个定位问题。但是,它提供了可靠的跨浏览器解决方案。唯一的缺点是,在图像“按住”位置之前似乎有一点点延迟。 (至少在FireFox中)。显而易见的解决方案是让容器在调整容器大小后显示图像(解决方案2)

答案 1 :(得分:0)

这可能值得一试。在检查小提琴时,我注意到#wrapper1的宽度为400px,#wrapper2的宽度为399px。为了保持一致性,我将#wrapper2的宽度更改为400px。

我添加了背景尺寸:封面;因为按钮图像的大小与其容器的大小不同。尝试一下,看看你的想法。

如果您需要将#wrapper2保持在399px,则将下面代码中的背景位置更改为background-position:左上角;使用background-size:cover;。

当前代码的另一个选项是使背景图像与其12px x 12px容器的大小相同,使用background-position:左上角;并删除背景颜色。创建按钮背景时,如果背景与容器的大小相同,则会很有用。

注意:您还可以使用CSS样式在div上创建按钮外观,而不是使用图像。


#wrapper1 {width:400px;}
#wrapper2 {width:400px;}
#container {
width:12px;
height:12px;
background-repeat:no-repeat;
background-position:center center;
background-size:cover;
-webkit-background-size:cover;
-moz-background-size:cover;
-o-background-size:cover;
background-image:url(data:image/gif;base64,R0lGODlhCQAJALMAANLNve/s58a7rd7Vznuatf////f39wAAALXD1vfz7+fj3tbTxsa6pdbPxt7b0sa2pSH5BAAAAAAALAAAAAAJAAkAAAQoEJFJiSw4l6mxmUYYJgp4nKczJUngKsOkOMOyNMAECALDPAJLhYKIAAA7);
}