-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
Use case
Unlike mobile where high density is ubiquitous, only a portion of devices on desktop can afford to have 2x or more device pixel ratio. Meanwhile, the density baseline is slowly going up so many users end up with a fractional scaling factor like 1.25x.
Fractional scaling creates rounding problems: UIs designed for a integer pixel grid now no longer snaps to it. Flutter chooses the approach to happily draw at fractional coordinates, which allows the layout to be more scale independent. However, this comes with blurring/antialiasing artifacts, and this can be especially noticeable to some people at lower DPI.
A screenshot of Chicago's gallery below (at 125% scale) demonstrates the blurred borders.
You can compare this with the UI at 100% scale, where the borders snap to the pixel grid. The borders are much more crisp this way.
Pro tip: view at 100% scale: that is, if your system scale is 125%, then you need to set the browser zoom to 80%.
Proposal
The web platform already have a sensible answer to this question. I use Firefox as my daily driver, and its behavior is described as below:
We’re trying to meet a bunch of constraints that can’t all be satisfied at the same time (the proof is left as an exercise to the reader, though I may have actually written it out once in a Bugzilla comment):
- 4 adjacent objects of width/height 25% (for example) starting at one edge of a container should end exactly at the other edge; there should never be an extra pixel in the container and they should never be wrapped due to being a pixel to wide
- objects that are logically adjacent should always touch visually; there should never be a pixel gap or a pixel of overlap due to rounding error
- objects given the same width should occupy the same number of pixels
- object boundaries should always (visually) be aliased to a specific pixel boundary in the display (they should never be blurred)
The one [Mozilla] sacrifices is typically (3), except for borders where we sacrifice (1) by rounding the widths to pixel boundaries much earlier.
Source
So boxes are snapped to the grid after layout, as the <0.5px distortion would likely be unnoticeable. Borders on the other hand needs to have their width rounded before layout, that is, a 1dp border at 125% scale becomes 0.8dp, in addition to being snapped to the grid after layout.
As a final note, this behavior probably should be opt-in, just like how people have been fighting for hinted fonts vs unhinted fonts for ages.
A related issue is #31707, but it proposes to not support the feature described in this issue. The floating point hack, also mentioned #31707, happens in logical pixels, and therefore it does not contributes to crispness in any way.

