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 :: Graphics: WebRender, defect)
Tracking
()
People
(Reporter: hildobijl, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: reproducible)
Attachments
(2 files)
Updated•9 years ago
|
Updated•9 years ago
|
Comment 3•2 years ago
•
|
||
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.
Comment 4•2 years ago
|
||
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.
Updated•2 years ago
|
Comment 5•2 years ago
|
||
Comment 6•2 years ago
|
||
screenshot of reduced testcase 1 in Firefox vs Chrome: https://bugzilla.mozilla.org/attachment.cgi?id=9282271
Updated•2 years ago
|
Updated•2 years ago
|
Comment 11•2 years ago
|
||
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.
Comment 12•2 years ago
|
||
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...
Comment 13•7 months ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #12)
Other browsers are going to match our behavior here and it's not clear there's a terribly-better behavior around
Do we know if/when that's going to happen? I think some of it was happening in https://issues.chromium.org/issues/40178820 for a little while, but I'm still seeing Chrome and WebKit both render my attached reduced testcase 1 with fuzzy antialiased borders. I'm not sure if that's because they have special-cases for borders less than 1px wide, or if they never finished implementing this change, or something else.
Even if other browsers do end up matching us here, we might want to add some sort of mitigation for print-preview in particular (like the WebRender mitigation in comment 12), to avoid having borders mysteriously disappear in print-preview, per the last bit of bug 1775345 comment 0 (see screenshot https://bug1775345.bmoattachments.org/attachment.cgi?id=9282272 ).
(This came across my radar again today because I was print-previewing a page that had a <table>
with 1px-thick borders, with some bordered empty cells on the final page. That final page just looked entirely blank in print-preview, which was confusing & looked like Firefox was mistakenly generating a final blank page.)
Comment 14•7 months ago
•
|
||
Looking at the Blink bug about border-snapping, it seems their feature-flag for this was called SnapBorderWidthsBeforeLayout
which shipped to release in v109 per https://chromestatus.com/feature/4651561863610368 and seems to have stuck. I think that (and the associated WebKit changes) are the thing that Emilio was referring to in comment 12 as other-browsers-going-to-match-us (correct me if I'm wrong though).
I think the last paragraph of my comment 3 is still an accurate description of the compat situation here -- Firefox optimizes for keeping borders crisp, even in the face of transform
with fractional scales, whereas other browsers do not (and hence scaled-down borders still show up [albeit in a fuzzy/antialiased form] for them, whereas they entirely disappear for us).
Comment 16•6 months ago
|
||
I think we should move this to graphics given the comments above. If we were to fix this, it should be by antialiasing borders, not by changing layout / style computation.
Description
•