Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
dholbert opened this issue Jan 20, 2023 · 9 comments
Open

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

dholbert opened this issue Jan 20, 2023 · 9 comments
Labels
css-page-3 Current Work

Comments

@dholbert
Copy link
Member

dholbert commented Jan 20, 2023

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.)

@dholbert dholbert added the css-page-3 Current Work label Jan 20, 2023
@fantasai
Copy link
Collaborator

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
Copy link
Member Author

dholbert commented Jan 20, 2023

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.

@dholbert
Copy link
Member Author

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
Copy link
Member

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
Copy link
Member Author

dholbert commented Jan 21, 2023

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
Copy link

faceless2 commented Jan 23, 2023

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

  • PrinceXML, Vivliostyle and page.js will accept 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"
  • When given a margin size that would result in the content area being less than or equal to zero, AH Formatter, PDF Reactor, Prince, typeset.sh, Weasyprint all complete. Vivliostyle and pagejs crash, as does our own BFO Publisher (now on my TODO).

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
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

(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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-page-3 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants