Closed toebes closed 4 months ago
If you need me to generate a smaller example showing individual problems, don't hesitate to ask.
Thanks for the report. I was able to reproduce in Firefox Nightly, and Firefox Release.
Reproducible issues are moved to our Bugzilla component; please see: https://bugzilla.mozilla.org/show_bug.cgi?id=1907822
Closing as moved.
[qa_29/2024]
Hi @toebes - I'm only seeing one difference (aside from font subtleties) between Firefox and Chrome, and it's a case where Firefox is honoring a forced pagebreak that the content is requesting, and Chrome is ignoring it (near the top of page 2).
I'm not entirely sure which behavior is correct -- I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1917145 on it with a reduced testcase -- but in the meantime I think you can avoid that difference by removing pagebreak
from this element in your testcase:
<div class="question pagebreak">
With that addressed, I'm not seeing any other substantial differences. Would you mind retesting and seeing if you're still seeing differences between Firefox and Chrome? And if you are, maybe share PDFs and/or screenshots to highlight the issues? Thanks!
Remember that this is a reduced case. I didn't want to burden you with the 20 page version.
Removing the pagebreak breaks lots of cases and is there to ensure that everything is paginated correctly. In theory the pagebreak should be innocuous when you are already at the start of a page.
To show the differences, I generated this from your test case: here's the Firefox version which ends up as 5 pages and if you look at the first page, the table is cut off to the right. Firefox-Bug.pdf
Here's the Chrome version which is only 3 pages (as expected). Chrome-OK.pdf
Please let me know what else I can provide. If you want to see the extreme case you can go to:
toebes.com/codebusters/TestManage.html?importURL=Samples/NC_C_Regional_1_2024.json
Then click on Test Packet
and then the Print
button. It should be a 20 page document with the first page not being numbered and all subsequent pages numbered 1-19. With Firefox you get 26 pages with the last page numbered as Page 12.
Remember that this is a reduced case. I didn't want to burden you with the 20 page version.
Removing the pagebreak breaks lots of cases and is there to ensure that everything is paginated correctly.
Sure -- I wasn't suggesting you remove all requested pagebreaks. :) Let me go into a bit more detail about why that one is troublesome...
In this particular case, the testcase is essentially requesting two pagebreaks in a row. Specifically, right now the content on the original reduced testcase looks like this:
<div class="page">
<div class="head">2024 Science Olympiad National Codebusters Division B</div>
<div class="headright">Team Number:_B_________</div>
<div class="foot">Page 1</div>
<div class="question pagebreak">
And here, both the page
and question pagebreak
elements have page-break-before:always
:
.page {
[...]
page-break-before: always;
[...]
}
[...]
.pagebreak {
page-break-before: always;
}
This means the content is essentially requesting a page-break before each of those elements. That's why the first bit of content (notably the head
/headright
) end on on one new page, and then the question itself ends up on another page, in Firefox and Safari at least.
I think technically Chrome is correct because the second forced-pagebreak here is supposed to be propagated to its parent since it's the first child (or the first non-abspos child, at least), which means the parent is essentially requesting two pagebreaks at the exact same spot (once explicitly, one propagated from the child), which results in a single break. At some point Firefox and Safari will implement those page-break propagation rules (maybe in this Firefox bug -- forced page-breaks in Firefox are a bit hairy and are something we'd like to rework, but we probably won't get to it in the next few months at least).
In the meantime, if you're looking for ways to work around this issue, you might try avoiding this sort of "double-page-break-request" where the content has two page-break-before:always
elements in a row and is relying on the browser to coalesce them into a single pagebreak.
Hopefully that makes sense and might be workable, if you're interested in ideas for workarounds. Thanks again for the bug report!
To show the differences, I generated this from your test case: here's the Firefox version which ends up as 5 pages and if you look at the first page, the table is cut off to the right. Firefox-Bug.pdf
Thanks for sharing this -- so for me, in order to get that "cut-off-on-the-right" issue (and in order to get a 5th page), I have to activate a non-default setting -- I have to choose "Scale: 100%" in the Firefox print dialog** (in the "More Settings" expandable section).
Could you check if you have that setting toggled? If so -- I'll bet things improve for you with the "Scale: Fit to Page Width", as shown here: (that's the default setting, in both Firefox and Chrome -- "Fit to Page Width" in Firefox, and "Scale:Default" in Chrome.)
If you want to see the extreme case you can go to:
toebes.com/codebusters/TestManage.html?importURL=Samples/NC_C_Regional_1_2024.json Then click on
Test Packet
and then the
Thanks. So, good news -- analyzing that extreme case, I can get Firefox to match Chrome with fairly-minimal workarounds. Details:
So first, to clarify -- in Chrome, that document actually gives me a 13-page print-preview & PDF (not 20), with the first page not being numbered and the final page being numbered 12. (I suspect that's what you meant to say, rather than 20-page-document etc. - I'm guessing those counts came from a different page that you were also considering linking here.)
In Firefox, I get 25 pages (with lots of blanks pages), not quite 26 -- I only get 26 pages (the count you mentioned) if I choose the non-default "Scale: 100%" setting per my previous comment. With the default "fit to page width", I only get 25 pages of output.
And if I add the following styles to avoid redundant pagebreak-requests, then Firefox only gives me 13 pages of output, and they exactly match the output that Chrome gives, to my eye (aside from minor font differences).
.page > .pagebreak { break-before: initial !important; }
.page { break-after: initial !important; }
Here's the Chrome output that I get from this document: chrome.pdf
Here's the output that I get with Firefox with the above two CSS styles added to the stylesheet (to override some of the styles that are otherwise requesting double-pagebreaks that Firefox doesn't currently coalesce together): firefox-with-workaround-css.pdf
(side note: given that "Scale: Fit to Page Width" and "Scale: 100%" produce different results, that's actually a good clue that the page here is using some explicitly-sized content that's wider than the available space on the page. That's why stuff gets clipped when you ask for 100% scale, and why it gets scaled down to avoid clipping when you use the default "Fit to Page Width".
Specifically looking at the clipped elements on the first page in the reduced testcase, we have this for the "nameline" (the section where "Team numb[...]" gets clipped):
table.nameline {
[...]
width: 50rem;
And we have this defining the size of the scoring table below that (note that there are 5 th
elements, so we've got 5*11 = 55rem).
table.testscores th {
[...]
width: 11rem;
}
1rem
is 16px
here, so 50rem
is 50*16px = 800px
and 55rem
is 55*16px = 880px
here.
And in Firefox at least, 800px is slightly wider than the available width on a US Letter page with 0.5in
-wide margins. Here's a testcase to visualize this: data:text/html,<div style="width:800px; height: 100px; border: 5px solid black; box-sizing: border-box">
Chrome has an interesting behavior where they seem to force "fit to page width" even if you try to choose a large scale factor. But if you try reducing the scale factor, you can see that ~92% scale is where 800px exactly fills the page area (with default margins), and they seem to refuse to scale up beyond that (including to 100%) even if you ask them to.
So, bottom line, this is my diagnosis of what's going on:
@toebes I hope the above helps, particularly my notes with good news on the extreme case. Let me know if you have further questions about what's going on here; otherwise I'm hopeful that it's not too tricky to work around this in the meantime (e.g. using CSS similar to my [...]: initial !important
rules quoted above -- or rather removing the CSS declarations that those ones are stomping on), should you choose to do so.
Some great observations! Thank you.
I've fixed the width issues on that score table (thank you for pointing that out) and it works "better" as long as they specify scale to width. Scale to 100% still doesn't behave as expected (you can see the page number on the subsequent page). I hope to get that pushed out to production after a bit more testing.
One thing that I did want to point out is that the .page style has a page-break-inside: avoid;
which might have some bearing on bug 1772396 being applied to this case.
.page {
page-break-inside: avoid;
padding: 0.5in 0in 0.25in 0in !important;
position: relative;
width: 100%;
height: 100%;
page-break-after: always;
page-break-before: always;
}
it works "better" as long as they specify scale to width. Scale to 100% still doesn't behave as expected
That's good news, though if you're still seeing a difference between those configurations in Firefox, then that's an indication that you've still got some element with too large of a specified width to actually fit on the page. If everything is fitting horizontally, then "Fit to Page Width" and "scale: 100%" would produce exactly the same layout.
(Note: Chrome has a bug in these scale settings, meaning their "scale:100%" layout can't be relied on -- so if you're seeing good results from them with scale:100%
, don't trust it too much -- it might not remain good after they fix that bug. :) )
you can see the page number on the subsequent page
That indicates that your positioning for these page numbers is too large for them to fit in the available space on the page. (You happen to be getting lucky that "fit to page width" is having to scale stuff down, such that it happens to scale the heights enough to make stuff fit vertically too.)
Looking at your original testcase, I can see that this is trivially happening with the "Page 2" text that you mentioned was being pushed to its own page when printed at 100% scale.
Here's the relevant CSS from your testcase:
@page {
margin: 0.5cm;
}
.page .foot {
height: 0.25in;
[...]
position: absolute;
[...]
top: 10.5in;
}
.page .foot {
margin: 0.7em auto;
Those various offsets are placing the .foot
element beyond the bottom of the printable area on the page, which is why the text overflows onto another page.
Specifically, for a US Letter sheet of paper:
margin: 0.5cm
from the top and bottom (1cm
total), we're left with roughly 10.6in
of printable space on the page. (1cm = 0.4in, roughly, so we've got 11in - 0.4in = 10.6in
.).page .foot
CSS-rule quoted above asks for the top edge of .foot
to be 10.5in from the top edge of its page's printable area. That would put its top edge almost exactly at the bottom of the printable area (0.1in away). This is already too far down for the text to entirely fit. But that's also not the last offset we have to account for -- it moves down a bit further to account for the final CSS that I quoted above, margin: 0.7em
(which pushes that element further downwards by roughly 2/3 the height of a line of text, which is almost certainly beyond that 0.1in
-- i.e. fully off the page).To avoid that overflowing page number, you need to use smaller top
value there -- 10.5 is too tall and (when combined with the margins) is basically pushing that text off the page. (You might find things are more robust if you use bottom
-based indexing -- but that requires your .page
elements to be sized to precisely fill the actual page, which might lead to further rabbit-holes/whack-a-moles.)
One thing that I did want to point out is that the .page style has a page-break-inside: avoid;
Yup, I saw that -- that turns out not to be relevant here. Quoting the spec, "...a forced break value
effectively overrides any avoid break value
that also applies at that break point." https://drafts.csswg.org/css-break-3/#forced-breaks
("page-break-inside: avoid" also can't save you in cases where the content is simply positioned at too far of an explicit offset to be able to fit on the same page, as is the case with the .page .foot
CSS discussed above in this comment. :) In that situation, a page-break is unavoidable, unless there are additional scale factors coming into play.)
URL: https://toebes.com/codebusters/Samples/firefox_toebes_printing_example.html
Browser / Version: Firefox 128.0 Operating System: Windows 10 Tested Another Browser: Yes Chrome
Problem type: Something else Description: Printing doesn't format correctly Steps to Reproduce: This is an extract of a sample case of the set of tools for Science Olympiad Code Busters (https://toebes.com/codebusters/) that generate and print tests.
When we print the tests using other browsers (Chrome, Edge) we are able to get consistent formatting and output such that the page fits on the sheet of paper and text is rendered cleanly. However, in the past year or so we have received complaints from Firefox users that it doesn't format and print well.
I have run through the W3c validator to ensure that the HTML is valid.
If you load the file in Firefox and then print, you will notice several issues: 1) Firefox generates 5 pages instead of the 3 that it should. 2) The names of participants table ends up wider than the page. 3) The Score table on the first page is off the right hand edge of the page. 4) The header for the second page (Page 1) is on a page by itself 5) The footer for the second page (Page 1) is near the top of the third page 6) The text for the timed question appears too high on the page 7) The text for the timed question is in a slightly larger font such that it wraps early. 8) Similar problems are on the last page, with the header appearing nominally in the correct place 9) The footer for the last page is on a page by itself.
Note that I have experimented with multiple options for the print scale and margins, for purposes of comparison I set the margins to .5" all around and forced the scale to 100% in all three browsers.
I've uploaded an image showing a side by side comparison of the rendered first page.
View the screenshot
Browser Configuration
From webcompat.com with ❤️