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

Footer is not displayed anymore with recent Chromiums #290

Closed
maltoe opened this issue Dec 13, 2023 · 23 comments · Fixed by #291
Closed

Footer is not displayed anymore with recent Chromiums #290

maltoe opened this issue Dec 13, 2023 · 23 comments · Fixed by #291
Labels
bug Something isn't working

Comments

@maltoe
Copy link
Collaborator

maltoe commented Dec 13, 2023

Footer templates set via ChromicPDF.Template are not displayed anymore with recent Chromiums.

ChromicPDF.Template sets page dimensions and header/footer dimensions via rules in @page { ... } and sets preferCSSPageSize: true in the printToPDF call. Some time after Chromium 117, footers set via footerTemplate have disappeared (margin is there but blank).

Analysis so far

  • Somewhere in between Chromium 117.0.5938.62 and 119.0.6045.159
  • setting the page margins via printToPDF options (in inches) fixes it
  • but even if only margin-top is present in @page, it breaks again
    • even with preferCSSPageSize: false

Minified example of what is broken

@page {
  size: 210mm 297mm;
  /* or any other variation of specifying margin-top and margin-bottom */
  margin: 40mm 0 40mm;
}

See stylesheet for actual code.

Things we've tried

  • size vs. width/height in @page has no effect
  • removing the zoom rule from #header, #footer has no effect
  • keeping a margin-inline: ... is ok, but specifying top/bottom in the CSS immediately breaks it
@janwillemvd
Copy link
Contributor

janwillemvd commented Dec 13, 2023

We encountered the same here! It was introduced in one of projects on 4 October when we deployed a new release of our software with the latest image (Debian).

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 13, 2023

@janwillemvd can you pinpoint the chromium version where it broke? We currently only have 117.0.5938.62 as last known good and 119.0.6045.159 as broken.

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 13, 2023

script to reproduce this https://gist.github.com/maltoe/104d192430a059f3672cb7a8c7a3b1bf (assumes local chrome is affected and chrome 115 is run via docker)

image


another example a bit later: they have definitely also made changes to the "zoom" of footer/header and to the default font

image

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 13, 2023

potential culprits:

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

@janwillemvd We have worked around this in our apps now by not using ChromicPDF.Template anymore, but passing in the CSS manually (without any margin rule in @page) and with marginTop etc. passed as print_to_pdf option.

@janwillemvd
Copy link
Contributor

@janwillemvd can you pinpoint the chromium version where it broke? We currently only have 117.0.5938.62 as last known good and 119.0.6045.159 as broken.

Will check this afternoon and let you know!

@janwillemvd
Copy link
Contributor

@janwillemvd We have worked around this in our apps now by not using ChromicPDF.Template anymore, but passing in the CSS manually (without any margin rule in @page) and with marginTop etc. passed as print_to_pdf option.

Thanks, @maltoe, will try that!

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

Maybe a bit bold, but perhaps it may help: @mstensho - you've recently worked on related code in Chromium (e.g. this commit) -> Do you have any idea what has changed and what we can do to mitigate? Context in the issue description.

@maltoe maltoe added the bug Something isn't working label Dec 14, 2023
@mstensho
Copy link

Don't know why the footer would disappear, but the font size change is explained here: https://bugs.chromium.org/p/chromium/issues/detail?id=1509917#c3

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

@mstensho thank you for responding! 💜 Unfortunately just dropping the zoom rule doesn't fix it :/

Do you think it makes sense to file a bug at bugs.chromium.org? Is what we've been doing here even "officially" supported? I've found lots of examples about @page { margin: 0 } on the web (usually in combination with preferCSSPageSize: true), but nobody seems to be using @page { margin-bottom: <some non neg value> } to give space to the footer.

@mstensho
Copy link

@page { margin:0; } means no room for headers and footers, so that's definitely not going to help. Or is this a separate "print job" for headers and footers? In that case margin:0 seems right.

There is code in Chromium that checks whether the headers / footers overlap with the page area box [1], and omit any such headers / footers.

In the CSS at

<style>
* {
-webkit-print-color-adjust: <%= @webkit_print_color_adjust %>;
text-rendering: <%= @text_rendering %>;
}
@page {
width: <%= @width %>;
height: <%= @height %>;
margin: <%= @header_height %> 0 <%= @footer_height %>;
}
#header {
padding: 0 !important;
height: <%= @header_height %>;
font-size: <%= @header_font_size %>;
zoom: <%= @header_zoom %>;
}
#footer {
padding: 0 !important;
height: <%= @footer_height %>;
font-size: <%= @footer_font_size %>;
zoom: <%= @footer_zoom %>;
}
html, body {
margin: 0;
padding: 0;
}
</style>
:

 @page {
      width: <%= @width %>;
      height: <%= @height %>;
      margin: <%= @header_height %> 0 <%= @footer_height %>;
    }

Setting the 'width' and 'height' properties for the page context isn't supported (at least not yet), and it probably wouldn't do what you think, anyway. I would expect the 'size' descriptor to be used instead, i.e. something like this:

      size: <%= @width %> <%= @height %>;

Unless this is for a separate "print job" for headers / footers. Then you should probably just remove width / height and set margins to 0. But I don't know this framework, so hard for me to tell.

In the test, I don't think width and height are specified, are they? We have guards in Chromium against invalid page area sizes, e.g. if the total size of the margins are larger than the page box [1], which would result in a zero or negative page area. In such cases we fall back to the default page size and margins (ignore CSS completely). If you try to squeeze in a footer taller than the default bottom margin, it will be discarded, since it would overlap with the page area. See above. Are the headers and footers really 40mm? Looks smaller to me.

[1] https://drafts.csswg.org/css-page-3/#page-model

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

There is code in Chromium that checks whether the headers / footers overlap with the page area box [1], and omit any such headers / footers.

This seems to be pretty much what is happening. Can you point me to this code?

Setting the 'width' and 'height' properties for the page context isn't supported (at least not yet), and it probably wouldn't do what you think, anyway. I would expect the 'size' descriptor to be used instead.

Good to know, we've been using these properties and additionally setting paperWidth/paperHeight in the options, which probably does not make sense then. But with regards to this ticket, I have also tried @page { size } and it doesn't change anything.

Unless this is for a separate "print job" for headers / footers.

Don't know what a "print job" is in this context. The way this library works currently, in short:

  • prepend the CSS snippet you've found to the HTML source of the actual content, as well as the header and footer templates
  • using devtools APIs to set up a target and inject the content markup with Page.setDocumentContent
  • calling the devtools Page.printToPDF API with preferCSSPageSize: true, paperWidth/paperHeight and the footerTemplate and headerTemplate (and displayHeaderFooter: true of course); but without any margin* option

I was assuming that all page dimensions (including width and height) would be taken from the CSS with this setup.


But just to repeat, I've since changed this ^^ and my test is now using @page { size } and does not have any zoom rules anymore. Whenever I set any vertical margin in @page in the CSS (regardless of value, in any unit), the footer is not displayed anymore (since Chromium 118 or 119).

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

I was able to reproduce the behaviour using puppeteer, if that helps. I'm expecting to see 3 "hello" strings, but get only 2, with the footer one missing. Running Google Chrome 120.0.6099.71.

const puppeteer = require('puppeteer');

const html = `
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <style>
      @page {
        size: 210mm 297mm;
        margin-top: 40mm;
        margin-bottom: 40mm;
      }

      #header, #footer { font-size: 12pt; }
      p { margin: 0; }
  </style>
  </head>
  <body>
    <p>hello</p>
  </body>
</html>
`;

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(html);
  await page.pdf({
    path: 'output.pdf',
    displayHeaderFooter: true,
    preferCSSPageSize: true,
    headerTemplate: html,
    footerTemplate: html,
  });
  await browser.close();
})();

run with:

npm init -y
npm install puppeteer
node test.js

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 14, 2023

Also @mstensho thanks again for your invaluable help! 💜 much appreciated

@janwillemvd
Copy link
Contributor

@janwillemvd can you pinpoint the chromium version where it broke? We currently only have 117.0.5938.62 as last known good and 119.0.6045.159 as broken.

I can confirm that it's broken in our app which uses 117.0.5938.132 (running on Debian 12).

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 15, 2023

@janwillemvd ❗ you're right, 117 was broken for us, too. I thought it was the version we used before 119, but in fact that was only for a few days (and PDFs from the period are broken too)... So our last known good version is in fact 115.

@mstensho Would you like me to open a bug on bugs.chromium.org?

@mstensho
Copy link

A bug report sounds fine.

Also, I really meant to point to the code that performs the header / footer overlap testing yesterday, but it looks like I forgot. Sorry.

Here it is:
https://source.chromium.org/chromium/chromium/src/+/main:components/printing/resources/print_header_footer_template_page.html;l=124-127;drc=f6529c7990744370869e4ab2794caae6c46ba044

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 15, 2023

Thanks, I'll open that bug report in a second then.

The code you've linked I had found before and found it suspicious, but it should only apply to elements with a .text class, right? So the default header/footer elements match, but not my custom footerTemplate.

@mstensho
Copy link

Oh right, it needs to be .text, indeed.

@maltoe
Copy link
Collaborator Author

maltoe commented Dec 15, 2023

🎉 I think I've figured this out now. The problem is that we've been prepending the entire CSS snippet above to both the content HTML and the headerTemplate and footerTemplate options. The @page { } directives used to be ignored within headerTemplate and footerTemplate, but apparently the page margins are now applied to the headers and footers as well, which makes their content disappear (pushed outside their content boxes basically).

@mstensho This is certainly a behaviour change in Chromium since after 115, but probably a good one. Thanks again for your time.

For ChromicPDF, I'm going to simply split this CSS apart and not include any @page rules in the header and footer templates anymore.

maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
@janwillemvd
Copy link
Contributor

Wonderful, @maltoe! Will try it out asap!

maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
@luhagel
Copy link

luhagel commented Dec 15, 2023

Thank you so much @maltoe, really saving the day here <3

@mstensho
Copy link

Glad you figured it out! I'm not quite sure why page margins were ignored previously, but it certainly makes more sense to honor margins on a general basis.

maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
maltoe added a commit that referenced this issue Dec 15, 2023
Fixes [[#290]](#290)

Since Chrome 117 custom footers would not be displayed anymore when
configured via `ChromicPDF.Template`. Reason for this was that our
stylesheet was prepended to both the content markup as well as the
header and footer templates. The `@page` rule contains the page margins
which used to be ignored in the header and footer sections, but are not
applied and lead to the footer being pushes out of its content box.
Fixed by splitting `ChromicPDF.Template.styles/1` into `page_styles/1`
and `header_footer_styles/1` and removing the `@page` directive from the
header and footer styles.

Besides, this patch removes the `zoom` directive from the header and
footer templates for Chrome >= v120, as they have removed the default
4/3 scale-up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants