9

I'm trying to create a fluid CSS grid, it works in Firefox and IE8+ but NOT in Safari/Chrome/Opera where the sub-pixel rounding issue becomes visible:

http://jsfiddle.net/bJKQ6/2/

.column {
  float: left;
  width: 25%;
}

The main container has a width of 100%, and if you change the browser size in Safari/Chrome/Opera you can see how the rounded widths are inconsistent.

After extensive reads about the problem I understood that "there is no right or wrong solution" for the sub-pixel rounding, but the Firefox way seems the best compromise to me. (For example, if I set 4 divs at a width of 25% I expect the covered area to be 100%.)

I would like to know if there is a CSS only solution that I missed, or alternatively some JavaScript to solve the problem.

Thanks!

UPDATE: As of May 2014, Chrome 33 and Safari 7 seem to have picked up the "Firefox way".

Oliver Hader
  • 4,093
  • 1
  • 25
  • 47
gyo
  • 1,663
  • 1
  • 19
  • 28
  • I answered a similar question a few days ago here http://stackoverflow.com/questions/9914209/css-browser-pixel-rounding-overflow-hidden-with-percentages/9942854#9942854 while it doesn't end in all elements exactly the same width, it's probably as close as you're going to get without javascript. – Daniel Imms Apr 02 '12 at 13:37
  • Thanks for the answer. I'd like to get rid of the "row" wrapper to have more flexibility, I added another example in the fiddle showing a thumbs gallery without having to wrap each row. – gyo Apr 05 '12 at 13:40

2 Answers2

8

Stubbornella's OOCSS framework (links below) grids module deals with this by giving the last column the following overrides:

float:    none;
overflow: hidden;
width:    auto;

This allows it to occupy whatever width remains within the container.

A bit of browser-forking (IE, ptzsch…) is necessary to get the same behaviour: https://github.com/stubbornella/oocss/blob/master/core/grid/grids.css https://github.com/stubbornella/oocss/wiki/grids

Barney
  • 16,181
  • 5
  • 62
  • 76
  • Thank you Barney, the only drawback there is the lastUnit class which is kinda unflexible. – gyo Sep 19 '12 at 17:56
  • I know what you mean — I personally think structural class names are a necessary component of flexible HTML, but this does mean adding a lot of it in. Having said that, it's possible to avoid a fair bit of the extra classes if you're willing to drop support for those browsers that don't support advanced CSS 2.1 selectors: replace references to `unit` with `.line > *` and `.lastUnit` with `.line > *:last-child`. – Barney Sep 19 '12 at 19:16
  • Hey @gyo, I created a demo of the above here: http://jsfiddle.net/barney/7Bd8V/, then I went a step further and stripped out everything except the `line` class, for a stripped down case where we assume all fractional widths want to be equal width: http://jsfiddle.net/barney/32Q8B/ – Barney Sep 20 '12 at 14:18
  • I've added colors to check the columns and they still 'mismatch'. http://jsfiddle.net/barney/32Q8B/ However, I think we have to give up as this issue needs to be resolved by the browsers. Thank you again :) – gyo Sep 20 '12 at 15:08
  • Another issue is that each X items have to be wrapped in a 'line'. – gyo Sep 20 '12 at 15:11
  • I think it would be a bit much to not give any kind of classname whatsoever and expect the browser to guess that you wanted a set of elements to have equal width ;) can you try hitting the fork button on the fiddle, then save/update and share? You just sent me back the same link… – Barney Sep 20 '12 at 15:13
  • Oops sorry I didn't save it! Btw I've checked again your 'stripped out' solution and it's pretty smart. However, after a lot of investigation I think the sub-pixel problem needs to be tackled by using perfectly divisible numbers, and fluid designs need to use smart solutions to get around it. Thank you anyways for your help :) – gyo Oct 01 '12 at 09:07
  • 1
    I've selected your answer because the stripped down version of the OOCSS grid really inspired me... and I came up with this: http://jsdo.it/gyopiazza/lMgl/ – gyo Nov 02 '12 at 18:14
  • That's actually very neat — defining the fractional width on the parent is a much more sensible option. Nice work! – Barney Nov 05 '12 at 07:03
  • The great news is that Chrome v22 seems to render percent widths like Firefox, so no more sub-pixel problems! Well, except Safari and Opera... – gyo Nov 05 '12 at 09:55
  • I really wanted this to work and thought it might, and it works in most cases, but when the element drops down to the next line (say you have 10 boxes and only room for 9, you'd expect it to just drop down to the next line) it obviously renders the element with width auto which makes the element only as big as the content inside... Ugh, my search continues... :( – Cory May 19 '13 at 03:41
  • 1
    @Cory maybe (in the case of having 10 items) min-width: 10%; would be a good idea? In any case, creating a fiddle and a new question on StackOverflow would definitely get some participation... – Barney May 20 '13 at 08:43
  • min-width and width auto isn't a bad idea actually.... Let me try it out and get back to you with results. – Cory May 20 '13 at 12:47
  • Works! Thank you Barney! I'd been fighting with this for days! – Cory May 20 '13 at 13:03
0

It sucks there isn't a nice option for this that will round pixels up and down for each browser, but in lieu of that, I usually do:

.nested:last-child {
    float: right;
}
.nested:first-child {
    float: left;
}

This will float the last child to the right so the px unalignment isn't obvious, but if it's the only element (say a div that is 33% width), then it will continue to float left.

Cory
  • 604
  • 1
  • 6
  • 16
  • Same problem as I define here: http://stackoverflow.com/questions/9635347/fixing-sub-pixel-rounding-issue-in-a-css-fluid-grid/12371926#comment23915801_12371926 If the element needs to drop to the next line, it's floated right. I think the only proper solution has to be using a preprocessor and using ceil() and floor() (Stylus but SCSS has equivalents) for each element complete with vendor prefixes to round in the appropriate direction. I'll report back if I figure anything out... – Cory May 19 '13 at 03:43