Currently Muuri does not handle percentage based widths, heights, paddings or margins as gracefully as it could. It simply reads the dimensions _in pixels_, rounds them with Math.round() and finally caches the dimensions. There are two reasons for rounding. First one is that it makes the layout algorithm much faster in specific scenarios. The second one is that when we try to set _too_ accurate translate (e.g. 123.1234124px) values there are sometimes small (less than 1px) visible "gaps" between the items due to the way browsers handle subpixel rounding and rendering. When we deal with integers there are no such issues.
The biggest issue with the current implementation is that in specific scenarios the rounding causes percentage based items to position incorrectly. For example if width is set to 33.333333% the last item in the row is sometimes positioned incorrectly to the next row's first item.
There are plenty of ways to fix this issue so let's see what we come up with...
The simplest way is to just simply get rid of the roundings, but we gotta check carefully that it does not break anything. Also we could make the roundings optional via an option.
I think I found a pretty nice solution for this one. Let's add a new sub-option to layout option called dimensionFormatter. It takes in a function that will be used to format item and container dimensions when calculating the layout:
var grid = new Muuri('.grid', {
layout: {
dimensionFormatter: function (value, type, dimension) {
return Math.round(value);
}
}
});
// Or more simply
var grid = new Muuri('.grid', {
layout: {
dimensionFormatter: Math.round
}
});
The first argument (value) tells the actual dimensions value in pixels. The second argument (type) tells if this is the value of and item or a container, it is always either 'item' or 'container'. The third argument (dimension) tells if we are formatting width or height, it is always 'width' or 'height'.
This way Muuri could provide some sane defaults, but the user could fully customize the rounding logic if needed. I know from experience that this kind of feature might come in handy in a tight spot when dealing with percentage values.
Thinkin about this futher, I'm just gonna add a new sub-option to layout option called rounding, which is a boolean. It's true by default which means that everything works like before, the dimensions are rounded. When you set it to false Muuri will use accurate dimensions. For the accurate dimensions we need to do some edge case handling here and there to avoid rounding errors (e.g. 0.1 + 0.2 !== 0.3) and to make it work accurately with percentage based dimensions.
This is now done, at least for now. Will be released with v0.4.0.
Most helpful comment
Thinkin about this futher, I'm just gonna add a new sub-option to
layoutoption calledrounding, which is a boolean. It'strueby default which means that everything works like before, the dimensions are rounded. When you set it tofalseMuuri will use accurate dimensions. For the accurate dimensions we need to do some edge case handling here and there to avoid rounding errors (e.g.0.1 + 0.2 !== 0.3) and to make it work accurately with percentage based dimensions.