1px calculation problem with browsers (problems with subpixels)

I think this problem is common and picked it up here in SO itself, but could not find how to solve it.

Problem :

When you resize the window, you will notice that the height of the two images will be 1px different (which is expected when the browser changes the decimal values).

How do I fix this problem? I know I can do this using flexbox . But I think there is a better solution. Can you guys jump?

 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> 

or even here when I use 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> 

Edit : The problem does not exist in Firefox, but exists in Chrome.

Note that the problem does not occur when I use 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> 

or using floats and built-in blocks:

 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> 
+5
source share
4 answers

This is due to a Subpixel Problem .

Each image occupies 50% of the container. For example, if the container has a width of 100 pixels, each image will have a width of 50 pixels.

But the width of the container may be an odd number of pixels, for example. 101px. Then there are three reasonable possibilities:

  • Make one image 50px wide and the other 51px. Then the images will not be equally wide, even if you specify the same width for both of them.
  • Make both images 50 pixels wide. Then there will be a gap of 1px
  • Make both images 51 pixels wide. Then they do not fit, overflow the container or wrap it on the next line.

Each option has its drawbacks, but browsers currently prefer the first option. However, in this case, the images have an internal aspect ratio, so different widths will create different heights, and then a 1px gap is created horizontally, not vertically.

It seems that Firefox detects what, and thus makes the smaller image as tall as the other, violating the aspect ratio. Chrome prefers to use aspect ratio.

Unable to change this. It completely depends on the implementation:

The particularly strange part in all of this is that theres really no right, or wrong, here. As this behavior should the rendering mechanism is not determined by the CSS specification, having it remains until the implementation for rendering at its discretion.

+7
source

try this image grid response code http://codepen.io/mlegg10/pen/AXZGox change my img src = to your code will be

 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> 
+1
source

Since chrome doesn't seem to play very well with .5px values.
Here is a javascript solution to make the width always an even number, so the height will also be even:

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> 
0
source

Just thought of a different approach to this that could satisfy your needs ... instead of worrying about forcing image sizes, you can vertically align everything in height and then hide the bottom 1px wrapper div by adding a 1px tall pseudo element that has same color as background. This will solve the visual aspect that 1px images will be removed from each other. It will also hide the bottom 1px images, even if they are correctly aligned, but depending on your images, this may not be important.

 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%;} 

script: https://jsfiddle.net/w4ktweuo/1/

0
source

All Articles