浏览器的 1px 计算问题(亚像素问题)
Posted
技术标签:
【中文标题】浏览器的 1px 计算问题(亚像素问题)【英文标题】:1px calculation issue with browsers (sub-pixel problems) 【发布时间】:2017-01-05 16:47:06 【问题描述】:我认为这个问题很常见,并在 SO 本身中找到了它,但找不到如何解决这个问题。
问题:
当您调整窗口大小时,您会注意到两个图像的高度有时会相差 1px(这是浏览器调整尺寸时的预期)。
如何“修复”这个 UI 问题?我知道我可以通过使用flexbox
来做到这一点。但我想有一个更好的解决方案。你们能跳进去吗?
table
width:100%;
border-collapse: collapse;
img
display: block;
width: 100%;
<table>
<tr>
<td><img src="http://placehold.it/100x100"/></td>
<td><img src="http://placehold.it/100x100"/></td>
</tr>
</table>
当我使用display: table
时,甚至在这里:
.wrapper
width:100%;
display: table;
.wrapper div
display: table-cell;
img
display: block;
width: 100%;
<div class="wrapper">
<div><img src="http://placehold.it/100x100"/></div>
<div><img src="http://placehold.it/100x100"/></div>
</div>
编辑: 这个问题在 Firefox 浏览器中不存在,但在 Chrome 中存在。
请注意,当我使用 flexbox
时,问题不存在:
body
margin: 0;
.wrapper
width:100%;
display: flex;
.wrapper div
flex: 1;
img
display: block;
width: 100%;
<div class="wrapper">
<div><img src="http://placehold.it/100x100"/></div>
<div><img src="http://placehold.it/100x100"/></div>
</div>
或使用浮点数和内联块:
body
margin: 0;
.wrapper
width:100%;
display: block;
.wrapper div
display: inline-block;
float: left;
width:50%;
.wrapper:after
content: '';
display: inline-block;
clear:both;
img
display: block;
width: 100%;
<div class="wrapper">
<div><img src="http://placehold.it/100x100"/></div>
<div><img src="http://placehold.it/100x100"/></div>
</div>
【问题讨论】:
表格用于表格数据,您应该使用 flexbox 或其他 css 选项来处理图像 实际上我正在寻找除了我在问题中提到的 flexbox 之外的解决方案 flex 是您的 html 代码描述的最佳选择 @yousefsamipadding
不起作用-尝试调整浏览器大小
img width: calc(100% + 2px);
?
【参考方案1】:
只是想到了一种可能满足您需求的不同方法...而不是担心强制图像大小,您可以将所有内容垂直对齐到顶部,然后通过添加隐藏包装器 div 的底部 1px一个 1px 高的伪元素,与背景颜色相同。这将解决图像彼此相距 1px 的视觉问题。即使图像正确对齐,它也会隐藏图像的底部 1px,但根据您的图像,这可能根本不是什么大问题。
body width:501px; background:black;
.wrapperwidth:100%; display:table; position:relative;
.wrapper:after content:""; position:absolute; bottom:0; left:0; height:1px; width:100%; background:black;
.wrapper div display:table-cell; vertical-align:top;
img display: block; width:100%;
小提琴:https://jsfiddle.net/w4ktweuo/1/
【讨论】:
你是个天才。在玩了几个小时之后,我终于添加了一个 :before 和width:100%;height:100%;border:1px solid white;
,它与元素重叠并隐藏了任何不一致的子像素渲染。【参考方案2】:
因为 chrome 在 0.5px 值下似乎不能很好地发挥作用。 这是一个使宽度始终为偶数的javascript解决方案,因此高度也将是偶数:
https://jsfiddle.net/hhmsqtz6/1/
$(document).ready(function()
resizeToEven();
);
$(window).resize(function()
resizeToEven();
);
function resizeToEven()
$('tbody').width(function(i, w)
var parentwidth = $('tbody').parent().width();
return (parentwidth - parentwidth % 2);
);
table, tbody, tr
width: 100% !important;
border-collapse: collapse;
display: flex; /* I had to made them flex, other display wasn't working */
img
display: block;
width: 100%;
height: auto;
td
padding: 0; /* put padding, to remove the gap */
/* set the width, because when right clicking it gets all messed up (at least it did, in my tests) */
width: 50%;
html
background: black;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><img src="http://placehold.it/100x100" /></td>
<td><img src="http://placehold.it/100x100" /></td>
</tr>
</tbody>
</table>
【讨论】:
【参考方案3】:试试这个响应式图像网格代码http://codepen.io/mlegg10/pen/AXZGox 将我的 img src= 更改为您的代码
img
width: 100%;
height: auto;
/* SECTIONS */
.section
clear: both;
padding: 0px;
margin: 0px;
/* COLUMN SETUP */
.col
display: block;
float:left;
margin: 1% 0 1% 1.6%;
.col:first-child margin-left: 0;
/* GROUPING */
.group:before,
.group:after content:""; display:table;
.group:after clear:both;
.group zoom:1; /* For IE 6/7 */
/* GRID OF TWO */
.span_2_of_2
width: 100%;
.span_1_of_2
width: 49.2%;
/* GO FULL WIDTH AT LESS THAN 480 PIXELS */
@media only screen and (max-width: 480px)
.col
margin: 1% 0 1% 0%;
@media only screen and (max-width: 480px)
.span_2_of_2, .span_1_of_2 width: 100%;
<div class="section group">
<div class="col span_1_of_2">
<img src="http://www.irishtimes.com/polopoly_fs/1.2614603.1461003507!/image/image.jpg_gen/derivatives/box_620_330/image.jpg">
</div>
<div class="col span_1_of_2">
<img src="http://www.irishtimes.com/polopoly_fs/1.2614603.1461003507!/image/image.jpg_gen/derivatives/box_620_330/image.jpg">
</div>
</div>
【讨论】:
全屏查看codepen,然后慢慢缩小尺寸,观察它如何保持纵横比,然后将图像堆叠在窄屏中 我经常使用那个网格系统。看看这个页面就可以自定义了responsivegridsystem.com/calculator【参考方案4】:那是因为Sub-Pixel Problems。
每个图像占用容器的 50%。例如,如果容器是 100px 宽,则每个图像将是 50px 宽。
但容器的宽度可能是奇数个像素,例如101 像素。那么有三种合理的可能性:
将一张图片设为 50 像素宽,另一张设为 51 像素。然后,即使您为它们指定了相同的宽度,图像的宽度也不会相同。 将两张图片设为 50 像素宽。那么会有1px的差距 将两张图片设为 51 像素宽。然后它们就装不下,溢出容器或包装到下一行。每种选择都有其缺点,但如今的浏览器似乎更喜欢第一种选择。但是,在这种情况下,图像具有固有的纵横比,因此不同的宽度会产生不同的高度,然后会在水平方向而不是垂直方向创建 1px 的间隙。
似乎 Firefox 检测到了比,因此使较小的图像与另一个图像一样高,从而破坏了纵横比。 Chrome 更喜欢强制执行纵横比。
没有办法改变这一点。它完全依赖于实现:
在所有这一切中,特别奇怪的是,真的没有 对或错,在这里。这种行为应该如何发挥作用 渲染引擎不受 CSS 规范的限制,具有 它留给实现来按照它认为合适的方式呈现。
【讨论】:
感谢您的精彩解释 :) 所以我猜 flexboxes 打破了纵横比?除此之外还有其他选择吗? @kukkuz 由于规范没有指定在这些情况下应该发生什么,你不能依赖任何东西。您可以尝试不同的方法并使用适用于大多数浏览器的方法,但未来或过去的版本可能会有所不同。以上是关于浏览器的 1px 计算问题(亚像素问题)的主要内容,如果未能解决你的问题,请参考以下文章
移动端1px像素解决方式,从1px像素问题剖析像素及viewport