有一段时间我感到很困惑,我的居中背景图片在容器中没有像素完美对齐。我什至在同一个浏览器但不同的窗口中得到了不同的结果
我终于知道发生了什么,但我仍然缺少一个强大的跨浏览器解决方案。
案例:我正在使用 javascript 开发可折叠的 TreeView 。一切正常,但在某些情况下,折叠/展开按钮向左偏移了一个像素。
这些按钮的图像是用户可定义的,以及它们出现在其中的容器的大小(宽度)。图像绘制在这些容器的中心,background-position: center center;
。现在有些情况下图像无法完全位于容器的中心(例如,将 9px 的图像居中放置在 20px 的容器中,两边有 1 像素的差异)。这应该没有问题,只要我们在浏览器如何处理这个问题上有一致的行为。
但这就是它变得困惑的地方:我已经在以 margin:0 auto;
为中心的包装器中实现了这个 TreeView ,该包装器基于浏览器视口(viewport)。这是当视口(viewport)居中和背景居中都不完全适合像素边界时我得到不同的结果。
这可能很难理解,所以我把问题压缩成 fiddle :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 显示了我描述的问题。尝试调整浏览器窗口的大小,然后看到按钮从一侧跳到另一侧。
我的问题是:我怎样才能获得至少相同的结果,同时又不失去按钮/容器/包装器大小和样式的灵 active 。
编辑:这是一张说明我的用例的图片:
蓝色标记的区域是容纳折叠按钮的容器。该区域始终为正方形,但大小可能会有所不同。该按钮可以是任何小于此容器的图像,并直接放置在线条相交的顶部。图像不应发生拉伸(stretch)或缩放。在此示例中,按钮太靠左了。调整浏览器窗口的大小会使图像跳入和跳出正确的对齐方式,如上面的 fiddle 所述。
最佳答案
似乎没有办法解决这个问题,只能在内部图像无法居中像素完美时调整图像容器的大小,以在定位上具有一致的跨浏览器行为。因此,我需要在服务器端或客户端获取图像元数据。
服务器端(一): 使用getimagesize和 getimagesizefromstring显然是要走的路。但后来我在当前用例中遇到了一个问题:树是使用 AJAX 呈现的,图像的相对 URL 与 AJAX 脚本的位置无关。
问题:
因此,为了使其正常工作,我必须同时传递 URL 和绝对路径(或单独传递绝对路径,并通过从中剥离 $_SERVER['DOCUMENT_ROOT']
来计算 URL)。对于尝试实现此树模块的开发人员而言,这种方法似乎违反直觉和限制。所以我放弃了这个想法。
服务器端(二): 在设计时询问图像尺寸。简单明了,将责任交给实现者。
问题: 不是很优雅,但它有效:)。 (解决方案一)
客户端:
我已经将两个图像都放在一个隐藏的 DIV 中,并且我从 onload 事件中获取了图像的大小。如果根据此数据,容器内使用的图像出现偏心(image.width%2 != container.width%2
,image.height%2 != container.height%2
),我循环遍历这些容器并将它们的宽度或高度调整一个像素。
问题: 我不喜欢将隐藏元素与触发器一起用于解决此定位问题的唯一目的的想法。但是,它提供了可靠的跨浏览器解决方案。唯一的缺点是在图像“定位”之前似乎有轻微的延迟(至少在 FireFox 中)。显而易见的解决方案是让容器在 调整容器大小后显示图像。 (解决方案 2)
关于html - 居中容器内的 CSS 图像居中会产生不可预测的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26078490/