Browsers experiencing a 1px calculation dilemma due to sub-pixel issues

I've come across a common issue here on SO, but I'm struggling to find a solution.

Problem:

When resizing the window, sometimes the height of two images differ by 1px (expected behavior when the browser adjusts dimensions).

How can I address this UI issue? I know using a flexbox is an option, but I believe there might be a better solution. Any suggestions?

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>

Alternatively, when utilizing 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 issue doesn't occur in Firefox but does in Chrome.

Note that using a flexbox eliminates the issue:

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 you can use floats and inline-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>

Answer №1

The reason for this issue is due to what is known as Sub-Pixel Problems, which you can read more about on this website.

When each image takes up 50% of the container's width, complications arise if the container width is an odd number of pixels. This results in three main possibilities:

  • One image being 50px wide and the other 51px wide, causing unequal widths.
  • Both images being 50px wide with a 1px gap between them.
  • Both images being 51px wide, leading to overflow or wrapping issues.

While browsers typically opt for the first option nowadays, differences in handling aspect ratios can cause variations in how they render the images. Firefox may adjust the smaller image's height to match the larger one, while Chrome sticks to preserving the aspect ratio.

This behavior is implementation-dependent and not dictated by CSS specifications, as noted in the quote below:

"The especially strange part, in all of this, is that there’s really no right, or wrong, here. How this behavior is supposed to play out by the rendering engine isn’t dictated by the CSS specification, having it be left up to the implementation to render as it sees fit."

Answer №2

Check out this amazing responsive image grid example http://codepen.io/mlegg10/pen/AXZGox and feel free to customize the img src attribute according to your needs!

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>

Answer №3

Here's a unique solution to address your needs: Instead of worrying about adjusting image sizes, you can align everything vertically to the top and conceal the bottom 1px of the wrapper div by inserting a 1px high pseudo-element with the background color. This approach resolves the issue of images being slightly misaligned by 1px. Keep in mind that it may also hide the bottom portion of images if they are perfectly aligned, but this might not be significant depending on the nature of your images.

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

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

Answer №4

In order to address the issue of Chrome not handling .5px values well, a JavaScript solution has been devised to ensure that the width is always an even number, thereby making the height even as well:

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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Mapping data in reactJS involves using the `map()` function to iterate over

Whenever I try to use items.map, it returns an error saying items.map is not a function. I am working on my wishlist feature, retrieving data from localStorage, but I can't seem to perform the map operation successfully. How do I iterate over this da ...

What purpose is served by the use of '.src' in Next.js?

When working with Next.js, I encountered a situation where I needed to set a background image. After doing some research, I came across a solution that involved adding .src at the end of the image reference like this: import bgImg from '../public/imag ...

The value coming from the Datalist is indeterminable, as Datalist is dynamically created through AJAX requests

In my HTML code, I have a Select element and a Datalist element. The Select displays options for different states like NY or NJ, while the Datalist contains a list of school names that are generated dynamically using Ajax with PHP because the schools depen ...

How can I access a component variable within the styles in Angular?

Is it possible to utilize a variable width in my Angular 5 component template? I would like to achieve something similar to this: <style> input:checked + .slider:before { transform: translateX({{width}}px); } </style> The &apo ...

Exploring the issue: Using Safari, setting a min-height of 100% does not function properly within a flex-grow child

When testing my code in Chrome, Edge, and FireFox, I noticed that the innermost div fills its parent correctly using min-height: 100%. However, Safari does not display the same behavior. The green div is not completely covered by its children as expected. ...

Angular's Validator directive offers powerful validation capabilities for reactive forms

Referenced from: This is the approach I have experimented with: custom-validator.directive.ts import { Directive } from '@angular/core'; import { AbstractControl, FormControl, ValidationErrors } from '@angular/forms'; @Directive({ ...

Changing padding of a button causes surrounding elements to move?

Trying to make a button in CSS appear "pushed down" on :active, I decided to increase the padding-top by 2px and decrease padding-bottom by 2px. However, this adjustment seemed to affect the margins of other elements for some reason that eludes me. I am c ...

What is the best way to incorporate a delay into a button using the Polymer framework?

I am in the process of creating a Polymer-based webpage, and I want to include a link to the paper-button I have created. I have managed to link it, but I would like to incorporate a delay so that users can see the ripple animation after clicking. In orde ...

Align the text vertically within a list item

<ul style="text-align: center;"> <li style="margin: 0; padding-bottom: 23px; font-size: 32px; vertical-align: middle;"> <div style="font-family: 'Arial','sans-serif'; color: black; font-size: 17px;">[%code1%]</ ...

I am looking to develop a Chrome Extension that will produce a sound each time the "e" key is pressed

I'm having trouble getting this code to work. As a beginner, I would appreciate any guidance on what I might be doing incorrectly. { "manifest_version": 2, "name": "Maradona", "description": "Listen to Maradona", "version": "1.0", "browse ...

Incorporating text sections into a div container and adjusting the width

Currently facing an issue with the canvas element on my project. <div id="app-container"> <div id="canvas-container"> <div id="canvas"></div> </div> </div> In the CSS stylesheet, the following styles ar ...

Is there a substitute for bootstrap select in Rails?

In order to style select tags with Bootstrap, we had to utilize the gem: bootstrap-select However, due to the high volume of options in our data-heavy application, the select dropdowns are causing significant slowdown (loading times, drop down performance ...

Steps to insert a Drop-Down Sub-Menu

I'm just about finished with my navigation panel. Any tips on how to add a sub-menu? I currently have one in the Product page. Below is the HTML code containing the sub-menus: <nav> <ul> <li><a href="">HOME</a>&l ...

Adjustable dimensions for a collection of squares based on screen size

I am currently designing a grid composed of 1:1 squares and allowing the user to continually add more squares. My main goal is to ensure that the size of each square maintains its aspect ratio while being able to resize accordingly. The challenge lies in k ...

Tips for adjusting column spacing in HighCharts

Looking for some advice on how to make a chart container scrollable and properly space the labels and bars within a parent container with fixed width and height. The goal is to ensure all labels are visible and bars are well spaced. Any suggestions or tips ...

Troubleshooting Website Navigation Bar and Layout with HTML, CSS, and Bootstrap5

I am facing a challenge with navbar positioning. My navbar items are missing after adding the image below. I have attempted to adjust the element positions but to no avail :( I also tried to create a fixed-top navbar, but it didn't work either :( I ...

Showcase your skills in CSS, HTML, and Javascript

I attempted to search for something similar but came up empty-handed. I have two buttons. When I click one of them, I want to hide a certain division, but it's not working as expected. The divs d2 and d3 are initially hidden when the page opens, whic ...

Take away and bring back selections from dropdown menus

My HTML code consists of a select element with options and buttons: <select id="sel"> <option value="1">aaa</option> <option value="2">bbb</option> <option value="3">ccc</option> <option value=" ...

The text on the menu is not adjusting properly for small screens

Check out the jsFiddle link. The issue arises when the Result screen is set to the width of a mobile's screen. Instead of wrapping the text, it gets replaced by dots and cannot be scrolled to view the full content. Here is the code snippet: <a hr ...

Retrieve the data stored in a concealed input field within a specific row of a table

I am dealing with an automatically generated table that is populated with data from a database and built using jQuery. The table is created by appending the following tr variable to the main tbody section of the HTML code: Below you can find my code snippe ...