浏览器的1px计算问题(子像素问题)

时间:2016-08-29 15:27:23

标签: html css google-chrome firefox

我认为这个问题很常见,并且在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>
&#13;
&#13;
&#13;

甚至在我使用display: table时:

&#13;
&#13;
.wrapper{
  width:100%;
  display: table;
}
.wrapper div{
  display: table-cell;  
}
img{
  display: block;
  width: 100%;
}
&#13;
<div class="wrapper">
    <div><img src="http://placehold.it/100x100"/></div>
    <div><img src="http://placehold.it/100x100"/></div>
</div>
&#13;
&#13;
&#13;

修改: Firefox浏览器中没有此问题,但Chrome中存在此问题。

请注意,当我使用flexbox时,问题不存在:

&#13;
&#13;
body{
  margin: 0;  
}
.wrapper{
  width:100%;
  display: flex;
}
.wrapper div{
  flex: 1;  
}
img{
  display: block;
  width: 100%;
}
&#13;
<div class="wrapper">
    <div><img src="http://placehold.it/100x100"/></div>
    <div><img src="http://placehold.it/100x100"/></div>
</div>
&#13;
&#13;
&#13;

或使用浮点数和内联块:

&#13;
&#13;
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%;
}
&#13;
<div class="wrapper">
    <div><img src="http://placehold.it/100x100"/></div>
    <div><img src="http://placehold.it/100x100"/></div>
</div>
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:7)

这是因为Sub-Pixel Problems

每张图片占据容器的50%。例如,如果容器宽度为100px,则每个图像的宽度为50px。

但是容器的宽度可以是奇数个像素,例如101px。然后有三种合理的可能性:

  • 制作一张50px宽的图像,另一张51px。然后,即使您为这两个图像指定了相同的宽度,图像也不会同样宽。
  • 将两张图片都放宽50px。然后将有一个1px的差距
  • 将两张图片都放宽51px。然后他们不合适,溢出容器或包裹到下一行。

每个选择都有其缺点,但现在浏览器似乎更喜欢第一个选项。然而,在这种情况下,图像具有固有的纵横比,因此不同的宽度将产生不同的高度,然后1px间隙是水平而不是垂直创建的。

似乎Firefox检测到,因此使较小的图像与另一个一样高,打破了宽高比。 Chrome更喜欢强制使用宽高比。

无法改变这一点。它完全依赖于实现:

  

在所有这些中,特别奇怪的部分是,确实没有   是对还是错,在这里。这种行为应该如何发挥作用   渲染引擎不是由CSS规范决定的   它留给实现渲染,因为它认为合适。

答案 1 :(得分:1)

尝试此响应式图片网格代码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>

答案 2 :(得分:0)

由于chrome似乎与.5px值相比并不是很好 这是一个javascript解决方案,使宽度始终为偶数,因此高度也将是偶数:

https://jsfiddle.net/hhmsqtz6/1/

&#13;
&#13;
$(document).ready(function() {
  resizeToEven();
});

$(window).resize(function() {
  resizeToEven();
});

function resizeToEven() {
  $('tbody').width(function(i, w) {
    var parentwidth = $('tbody').parent().width();
    return (parentwidth - parentwidth % 2);
  });
}
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

只是想到了一种可能满足您需求的不同方法...而不是担心强制图像大小,您可以将所有内容垂直对齐到顶部,然后通过添加隐藏包装div的底部1px一个1px高的伪元素,与背景颜色相同。这将解决使图像彼此偏离1px的视觉方面。即使它们正确对齐,它也会隐藏图像的底部1px,但根据你的图像,这可能不是什么大问题。

body {width:501px; background:black;}
.wrapper{width: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/