Open Bug 1258112 Opened 9 years ago Updated 2 years ago

Firefox's border pixel-snapping behavior causes thin borders to disappear entirely when scaled down (e.g. via CSS Transform or print-preview)

Categories

(Core :: CSS Parsing and Computation, defect)

44 Branch
defect

Tracking

()

People

(Reporter: hildobijl, Unassigned)

References

Details

(Keywords: reproducible)

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 Steps to reproduce: Here's a JSFiddle as an example. https://jsfiddle.net/mxoa9s60/ In other words: make a div with a CSS scale property. Put inside of it a div with a (thin) border. Then watch how this border is affected by the scale. Actual results: The borders on the four sides are of different width. And this width is very unpredictable. Sometimes a border disappears altogether for low scales. But if you make the scale even lower, the border reappears and a border on some other side disappears. It's crazy. Expected results: The borders should all remain the same width. (And remain visible.) To be precise, when a border of "0.8px" is scaled by a factor "0.5", the resulting border should look exactly like it would've looked when given the width "0.4px" without scaling. Google Chrome does this well enough. Firefox doesn't.
Component: Untriaged → CSS Parsing and Computation
Product: Firefox → Core
Status: UNCONFIRMED → NEW
Has STR: --- → yes
Ever confirmed: true
Keywords: reproducible

Clarifying what sorts of outcomes are realistic here:

(In reply to Hildo Bijl from comment #0)

Expected results:

The borders should all ... remain visible

Let's focus on this^ request; I think this is the least-controversial expectation here.

To be
precise, when a border of "0.8px" is scaled by a factor "0.5", the resulting
border should look exactly like it would've looked when given the width
"0.4px" without scaling.

This is a reasonable intuition but it's a non-goal and is not actually how borders work in any browser.

In the absence of transforms, I think all browsers snap borders to whole-number display-pixel-values (at least, they do for borders less than 1px) -- so e.g. 0.4px will just round up to one display-pixel (and so will 0.01px), at computed-value-time (i.e. and it actually reserves & occupies that much layout space, rather than the specified tiny-fraction-of-a-pixel). This is interoperable and required for compatibility; you can try e.g. data:text/html,<div style="border: 0.01px solid black">Hi in various browsers and see that it occupies a full display-pixel (e.g. it's equivalent to border:1px solid black on a traditional non-HiDPI display resolution).

In contrast, transform:scale(0.5) is a paint-time effect and we don't get the opportunity to make the border specially-reserve-and-occupy a full display pixel of layout space when we apply a scaling transform. Chrome seems to use antialiasing to paint the scaled-down partial-pixel-width-border, whereas Firefox seems to still try to paint a whole number of pixels (possibly 0); we round down to 0px for sufficiently-small scales / sufficiently-thin borders. This outcome is not-great; ideally we should allow ourselves to paint fractional-width-borders as antialiased partial-pixels when we're scaling them, I think.

Also FWIW, I can see that the original testcase here renders without a top black border in old Firefox nightlies e.g. Firefox Nightly 48.0a1 (2016-03-19), but the whole black border paints in current Firefox Nightly (2022-06-21).

But if I reduce the scale to e.g. 0.2 or 0.5, I can still reproduce (the black border disappears).

I've got a clearer/more-comprehensive testcase on my dupe bug, which I'll repost here for clarity/convenience.

Attachment #8732527 - Attachment description: reporter's testcase → reporter's testcase (might not repro the bug anymore unless you use devtools to reduce the transform:scale(...) fraction)
Attached file reduced testcase 1 (deleted) —

screenshot of reduced testcase 1 in Firefox vs Chrome: https://bugzilla.mozilla.org/attachment.cgi?id=9282271

Summary: Firefox scales borders unequally, and sometimes the borders disappear altogether by scaling → Firefox's border pixel-snapping behavior causes thin borders to disappear entirely when scaled down (e.g. via CSS Transform or print-preview)
Severity: normal → S3

The severity field for this bug is relatively low, S3. However, the bug has 5 duplicates.
:emilio, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Flags: needinfo?(emilio)

Other browsers are going to match our behavior here and it's not clear there's a terribly-better behavior around. We could make WebRender force 1 dev px borders at paint-time too, but...

Flags: needinfo?(emilio)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: