w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.42k stars 647 forks source link

[css-page-3] Specify how to handle page sizes with zero area #8335

Open dholbert opened 1 year ago

dholbert commented 1 year ago

Filing this issue to hopefully get some clarification on two related issues that I came across recently when thinking about @page { size: ... } which I think need to be addressed in the spec, for the size descriptor in @page rules: https://w3c.github.io/csswg-drafts/css-page-3/#page-size-prop

(1) What should be done if 0 is specified for size? (for either or both of the width & height components)

(2) Or, for nonzero page sizes -- what should be done if the size isn't larger than the specified margins for the page?

(In case 2, the naive approach would produce a sheet of paper with zero space for content, which is not great.)

Based on my testing in https://bugzilla.mozilla.org/show_bug.cgi?id=1807985 , it looks like Chromium handles both of these by falling back, effectively treating the size as auto at used value time, I think. I suggest we add that to the spec.

(I've got a bunch of testcases attached to https://bugzilla.mozilla.org/show_bug.cgi?id=1807985 as well, FWIW.)

fantasai commented 1 year ago

I think the correct thing to do would be to have a zero-sized page content box. Otherwise you get vastly different behavior at size 0 and size 0.1px which is weird?

The fragmentation algorithms all require making progress, so this shouldn't result in infinite loops. It will give bad results, but you'd get basically those same results if you have 1px pages anyway...

dholbert commented 1 year ago

Yeah, infinite-loop-avoidance isn't my concern here. I agree that it's ~fine to just make a little forward progress on each page, shrug about content being clipped if necessary (e.g. a 16px-tall character on a 0.1px height page), and move on.

The open questions that motivated this, at least for size:0, were:

dholbert commented 1 year ago

So: closing out the thought, that's why I feel like size:0 should be treated as auto (scenario (1) in my initial comment here).

As for scenario (2), i.e. nonzero page sizes that still produce a 0-size page content box due to large margins: I can see "whelp, you get a blank page" being more justifiable there (and more possible to print-preview and produce PDF output).

However, RE your note about wanting to avoid "vastly different behavior at size 0 and size 0.1px" -- there is already a substantial discontinuity there, and it's unavoidable. A small-but-nonzero-sized page content box can still be filled with the page's background-color (for example), and it can even theoretically contain useful text content which can be zoomed-to-be-seen, if the user has their print scale set to "fit page width", as is the default in Firefox at least. (The output will be an extremely tiny PDF file, but it could contain tiny vector representations of text that can be zoomed in and viewed, at least in theory.) Whereas for a zero-sized page content box, it's just always blank, and there's no way around that. So: there's a substantial difference between 0 and 0.1px already. My suggestion is that we embrace this discontinuity and opt to make the "zero" side of it likely-useful instead of likely-useless.

Also: if we create a special case for 0-sized pages being treated as auto (as I think we should for reasons described in previous comment), then it's seems kinda reasonable to take that a small step further and apply the same fallback to zero-sized page boxes, for reasons described in this comment.

tabatkins commented 1 year ago

I agree that the discontinuity isn't great, but also that this is so far down the "you're doing something incredibly wrong" mineshaft that I'm fine with it. Heck, I'd support a UA-defined minimum size, below which the UA ignores you and treats it as auto.

dholbert commented 1 year ago

Heck, I'd support a UA-defined minimum size, below which the UA ignores you and treats it as auto.

Exactly, yeah. I think that's essentially what I'm proposing -- a UA-defined minimum size for the page content box (i.e. margin-adjusted size) -- and below that threshold, some set of @page-rule descriptors (size and potentially also margin, maybe others?) can considered to be degenerate and are effectively disregarded (i.e. their used value would be their initial value).

(In practice I think the minimum-valid-size might likely be "1 app unit" or some sort of equivalent, i.e. the smallest nonzero fraction of a pixel that we can represent.)

faceless2 commented 1 year ago

Sorry, a bit late to this. Some testing in various print formatters via https://printcss.live:

As an aside, PDF prior to PDF 2.0 also recommends a minimum page dimension of 3pt (4px). Going below this gives errors in Acrobat, weird results in macOS Preview.app, and in general I wouldn't expect pages smaller than this to be reliable rendered in PDF applications. I appreciate "recommends" is a bit woolly, and I also appreciate PDF is not the only game in town, but "vastly different behaviour" is what you're going to see for pages less than 4px on any side. I don't see why PDF's failing here should impose similar limits in CSS, but a note to that effect might be useful.

So I agree that size:0 should be treated as auto. But the page area (the inner dimensions after subtracting the margin) of <= 0 does seem to be widely accepted - it's no different to any other cases where content overflows. The results may not be useful, but they're not invalid - layout can complete.

dholbert commented 1 year ago

Thanks, @faceless2 -- that's useful context/history.

Given that there's prior art for allowing zero-sized page areas on nonzero-sized pages, I'm happy to withdraw the request to add any special cases for those (though that does mean that Chrome at least has some nonconfirming behavior on those & might want to change).

So: I think my proposal here is just to make the used value auto, for any size values that include a zero length for width and/or height. (I'd also be happy with a UA-defined minimum-size threshold below which values will be treated as auto, if that's better for some reason.)

dholbert commented 1 year ago

Given that there's prior art for allowing zero-sized page areas on nonzero-sized pages, I'm happy to withdraw the request to add any special cases for those (though that does mean that Chrome at least has some nonconfirming behavior on those & might want to change).

Update: we have actually encountered one case of a site depending on Chrome's behavior here. The site (https://www.theaa.com/ route planner) specifies @page { size: 16px; } for some inexplicable reason, when generating printable driving directions. Notably, that's a positive page size, but it's small enough that the page content box (the page area that @faceless2 referred to) will be <=0 once the default page margins are subtracted out.

Given this in-the-wild observation of a production site using a bogus 16px page size for intended-to-be-printed-onto-regular-sized-paper content, I'm leaning towards implementing the same graceful-fallback behavior that Chrome seems to have here, for compat & user-benefit. It's not obvious to me that the nonzero-pagesize-but-zero-page-area use-case is important/valid enough to support faithfully, if it creates the potential for this sort of footgun.

dholbert commented 1 year ago

(I forgot to mention -- if it's not clear, the upshot of this issue with https://www.theaa.com/ is that it produces a blank page when you try to print its driving directions in Firefox, and presumably in any other UA that faithfully honors the @page { size: 16px } rule. Whereas in Chrome, it prints as if that @page rule weren't present, because it seems Chrome is rejecting that size as bogus since it results in a <=0 page content area.)