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

Make background transparent in generated PDF (instead of white). #2084

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
5 participants
@pvandertak

pvandertak commented Dec 3, 2014

Previously, wkhtmltopdf rendered a white background explicitly. This makes it impossible to use the generated PDF as an overlay for another PDF (merging the PDFs using other tools). This patch removes the default-white background. Note that it is still possible to force the white background using <body style="background: white">, but I don't think that is normally useful.

Peter van der Tak
Make background transparent in generated PDF (instead of white).
This is useful if the PDF is used as an overlay on top of another PDF.
@ashkulz

This comment has been minimized.

Member

ashkulz commented Dec 4, 2014

That's a change in the default behavior which I'd hesitate to merge as-is. Ideally, we should either create new command-line option (--transparent-pdf and --no-transparent-pdf) with the default being --no-transparent-pdf.

@pvandertak

This comment has been minimized.

pvandertak commented Dec 4, 2014

I understand your reasoning, but let me describe why I think it should not be an option:

It used to fill only the part of the page up to the bottom of the contents (i.e. everything below the bottom of the rendered content would be transparent; the rest would be filled white). I consider that to be undesirable/unexpected behavior, and think it should not be default and not an option.

The only reason I see why the option would exist would be for backwards compatibility when people rely on that behavior (probably a very small minority). Most likely, if they rely on it, they mean to use <body style="background: white"> instead. If they really want the old behavior (which I think is very unlikely), they can still wrap their contents in a <div style="background: white">. Both seem to e like easy and obvious changes in case someone experiences the change in behavior.

It is up to you of course, but I think having an option for this would be over-conservative, unless I am missing some scenario (I admit that I'm not a (wkhtmlto)pdf expert).

@ashkulz

This comment has been minimized.

Member

ashkulz commented Dec 4, 2014

Can you add a screenshot demonstrating what you said? What you say does make sense though 😄

@pvandertak

This comment has been minimized.

pvandertak commented Dec 4, 2014

I keep stumbling upon new details here, and it is getting more confusing...

In general, the body defines the size of the background that is drawn. The body width seems to be equal to the page width (minus margins), and the body height depends on the contents. All but the last page are filled with the background color. If the body height is not an exact multiple of the page height (again except margins), then the last page will have a transparent background in the bottom: the remaining part of the page below the body. This happens consistently with <!DOCTYPE html> of without doctype with a document of at least two pages. Without doctype, for a single page document, the body background fills the entire first page. (An exception that I happened to use as a basis for my earlier testing... 😒) In conclusion, setting background: white (if it would work; see below) is no more reliable than the current default behavior, unlike what I wrote before.

It seems <body style="background: white"> does not work; I tested with <body style="background: orange">, which gives an orange background as expected, and assumed background: white would work too. Nope. Instead, it gives a transparent(/no) background! So, then what about <body style="background: transparent">? For whatever reason, that gives a white background! Somehow, white and transparent behavior are swapped. 😕 I analyzed it a bit further, and the actual commands that end up in the PDF are (0.12.1 MSVC 2013 x64 downloaded from the site):

background: white: no background drawn (does not make sense)
background: transparent: one white background layer is drawn (does not make sense)
background: orange (and other colors): one white background layer is drawn, and another orange layer is drawn on top (works; does not make sense)

My patch removes the white background layer in the transparent case and in the any color case, but does not add it in the white case. (I don't see how it could do that either; it seems to be a bug elsewhere.) With the patch, I thus end up with:

background: white: no background drawn (does not make sense)
background: transparent: no background drawn (works; makes sense)
background: orange (and other colors): a single orange layer is drawn (works; makes sense)

So it makes a little more sense, but that does make it impossible to get a truly white background...

As for screenshots, I uploaded a few PDFs instead: http://we.tl/USfZ13ElAe . red.pdf is simply a completely red PDF that I use so that white and transparency can be seen. Over that, I overlay a generated PDF based on this template:

<!DOCTYPE html>
<html>
    <body style="background: COLOR;">
        <div style="position: absolute; background: lime; width: 3cm; height: 22cm;"></div>
    </body>
</html>

where COLOR is either white, transparent, or blue. The resulting (merged) PDFs are background_*.pdf. blue works as expected. white and transparent seem to be interchanged. In all cases, the bottom part of the second page and all margins are transparent.

For the record, I used the following arguments: wkhtmltopdf.exe --margin-bottom 2cm --margin-left 2cm --margin-right 2cm --margin-top 2cm --page-size A4 --orientation Landscape --print-media-type --dpi 96 --disable-smart-shrinking --no-outline

PS. Interestingly, this means I can achieve what I wanted without any code changes, by setting background: white; it just makes no sense at all.

@ashkulz

This comment has been minimized.

Member

ashkulz commented Dec 5, 2014

I suspect that wkhtmltopdf/qt@2ce79ad is causing the first scenario; with your patch the behavior will be more logical and hopefully the above patch can be removed. I'll investigate it a bit further this weekend.

@pvandertak

This comment has been minimized.

pvandertak commented Dec 5, 2014

That sounds plausible. Thanks for investigating. :)

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jan 4, 2015

Hmm, trying it on a 0.13 build (i.e. unpatched Qt5) background: transparent does not seem to work. Can you tell me how you tested it, as the download link does not work?

@pvandertak

This comment has been minimized.

pvandertak commented Jan 4, 2015

I uploaded the same files again at:
http://vdtak.eu/files/wkhtmltopdf_transparency_test.zip

I tested it with the git HEAD version at that time, with and without my patch applied. The behavior seems to have changed with 0.13.

I uploaded a test case for reproduction here: http://vdtak.eu/files/wkhtmltopdf_transparency_test_2.zip
test.bat runs 0.12 and 0.13 (both downloaded from the download page today) with background: white (test_white) and background: transparent (test_transparent). All output files are suffixed with _12 or _13 for 0.12 and 0.13 respectively, and then overlayed over a red background (red.pdf) using pdftk. The resulting pdfs are suffixed with _overlayed. For 0.12, it gives the "swapped" behavior as I described previously; test_white_12_overlayed.pdf should have been test_transparent_12_overlayed.pdf and vice-versa. For 0.13, it always seems to give a white background.

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jan 5, 2015

Actually on Windows it gives the background color of the default theme with transparent on 0.13 -- I use a theme called Marine from Windows 2000, which has a greyish background.

@abligh

This comment has been minimized.

abligh commented Jan 16, 2015

For anyone searching with how to get this to work unamended on 0.12, on Linux Ubuntu Trusty, here's what I've found.

On 0.12, I'm rendering with --no-background. By default, the following HTML draws a white background (even with --no-background):

<html>
  <head><title>Hello</title></head>
  <body>
    <h1>This is a heading</h1>
    <p>This is some text</p>
  </body>
</html>

Specifying a transparent background like this still produces a white background.

<html>
  <head><title>Hello</title></head>
  <body style="background: transparent">
    <h1>This is a heading</h1>
    <p>This is some text</p>
  </body>
</html>

But specifying a white background produces a transparent background!

<html>
  <head><title>Hello</title></head>
  <body style="background: white">
    <h1>This is a heading</h1>
    <p>This is some text</p>
  </body>
</html>

Therefore I respectively disagree about an option not being needed because the only way to get a transparent background at the moment appears to be to ask for a white background.

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jan 18, 2015

It looks like the Qt5 behavior is broken, see QTBUG-29040. I'll merge the commit as-is and create a separate issue for tracking the Qt5 behavior.

@ashkulz ashkulz added the Merged label Jan 18, 2015

@ashkulz ashkulz closed this in 5f89404 Jan 18, 2015

@ashkulz ashkulz added this to the 0.12.2.1 milestone Jan 18, 2015

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jan 18, 2015

Thanks for the contribution!

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jan 20, 2015

0.12.2.1 has been released, which includes changes related to this issue.

@pvandertak

This comment has been minimized.

pvandertak commented Jan 31, 2015

I finally got around to testing this, and it seems to work well. Thanks. :)

@nathan-muir

This comment has been minimized.

nathan-muir commented Feb 18, 2015

@ashkulz What is the nature of this change?

0.12.2.1 seems to have broken the transparent backgroun functionality for me. <body style="background:transparent"> sufficed in 0.12.2

I'm layering the pdf produced by wkhtmltopdf atop another pdf using apache pdfbox.

@ashkulz

This comment has been minimized.

Member

ashkulz commented Feb 18, 2015

@nathan-muir: please post a test case, as the earlier behavior was broken -- refer to the test cases posted above which did not work properly and now render OK with this change.

@nathan-muir

This comment has been minimized.

nathan-muir commented Feb 18, 2015

@ashkulz After attempting to produce a test case, I realise I was a bit too hasty!

Apparently my old code had a hidden "background:#fff;" which made it work with 0.12.2, and broke it in 0.12.2.1.

Thank you for this patch!

@jkrasnay

This comment has been minimized.

jkrasnay commented Jun 23, 2015

The default transparent background has an unfortunate effect on PDFs attached to emails and viewed on the Mac mail app. Mac mail renders the PDF's pages into the body of the email, but the transparency allows the background color of the email to show through. Setting body { background-color: white } only puts white behind the PDF content; margins and the portion of the page below the content are still transparent. Is there some other way to explicitly set the background color of the entire page?

@ashkulz

This comment has been minimized.

Member

ashkulz commented Jun 24, 2015

@jkrasnay: can you post a screenshot of how it looks like?

@jkrasnay

This comment has been minimized.

jkrasnay commented Jun 24, 2015

Here is a screenshot of the PDF inside the Mail app. The HTML body of the mail message has a grey background:

test-1

If you click on the PDF part of the email you can see the full extents of the PDF:

test-2

Opening the PDF in the Preview app (the PDF viewer for Mac) it looks OK.

test-3

@jkrasnay

This comment has been minimized.

jkrasnay commented Jun 24, 2015

Here is the HTML used for the email body:

<!DOCTYPE html>
<html>
<body style="background-color: #ccc">
  <div style="background-color: white; padding: 1in">
    This is the body of the email
  </div>
</body>
</html>

Here is the HTML used to generate the PDF:

<!DOCTYPE html>
<html>
<body style="background-color: white">
  This is the body of the PDF
</body>
</html>

Finally, the wkhtmltopdf command is wkhtmltopdf --page-size Letter --orientation Portrait test.html test.pdf

ashkulz added a commit that referenced this pull request Apr 14, 2016

make background transparent by default for headers/footers
This was already done for the main webpage in #2084, but was not
implemented for headers and footers. fixes #2416
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment