Open dholbert opened 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...
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:
If a browser were to faithfully honor size:0
, how would print-preview even work for that "page"? Browsers typically scale the 'virtual sheet of paper' to fit the print-preview viewport, so even extremely small sheets of paper can be usefully previewed. But you can't scale a 0-sized sheet of paper. So the user will just see: Here's your print preview: [nothingness], page 1 of 60
, which is not-great and arguably pretty broken.
Even if we disregard that UX concern -- suppose the user actually proceeds to print to PDF or to postscript. Does a valid file get produced, and can that file be usefully viewed in any viewer? i.e. is it even valid a .ps or .pdf file with zero width and/or height? (I'm actually legitimately not sure, but I suspect it'd be bogus.) I tested a little bit with gs
(ghostscript) locally and got an error when I tried to render some trivial existing PDF (orig.pdf
) onto a zero-size page:
gs -sDEVICE=pdfwrite -g0x0 -dPDFFitPage -o out.pdf orig.pdf
gs -sDEVICE=pdfwrite -g1x0 -dPDFFitPage -o out.pdf orig.pdf
gs -sDEVICE=pdfwrite -g0x1 -dPDFFitPage -o out.pdf orig.pdf
All of these^ command variants produce Unrecoverable error: rangecheck in .putdeviceprops
.
If I use 1x1
as the size in that command, though, then it completes just fine and produces a valid PDF.
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.
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.
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.)
Sorry, a bit late to this. Some testing in various print formatters via https://printcss.live:
size: 0
and will create a 0x0 page. AH Formatter, BFO, PDFReactor, typeset.sh and Weasyprint will not accept 0x0 as a page size, it's treated as "auto"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.
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.)
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.
(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.)
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 thesize
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 forsize
? (for either or both of thewidth
&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.)