4

I generated a PDF file using wkhtmltopdf from a html page. The html page uses tables which have 1 pixel borders. If I open the PDF with Acrobat or Foxit they randomly miss to draw vertical borders, but they appear if I zoom in. So I guess it's some kind of rounding error, because the lines are too thin?

If I print the PDF it looks good.

And I just realized, it only happens if I set a background-color.

How can I fix this?


Here's a sample PDF. The border separating the characters "a" and "b" disappears depending on the zoom factor. I generated this file like this:

echo "
 <html><body>
  <span style="border: 1px solid black; background-color:red;">a</span>
  <span style="background-color:red">b</span>
 </body></html>"
| wkhtmltopdf.exe - test.pdf
duedl0r
  • 9,289
  • 3
  • 30
  • 45
  • @yms: it should work, you have to click "Download This File". – duedl0r Dec 01 '11 at 14:43
  • It worked now...nevermind... by the way, have you tried modifing the argument --dpi? – yms Dec 01 '11 at 14:49
  • @yms: Thx, good point. I tested with different dpi (10-10000) but no success :( While I was at it I also tested --disable-smart-shrinking, no success either. – duedl0r Dec 01 '11 at 15:17
  • did you try with a lower resolution? if your lines in html are defined in pixels, then their width in pdf will be lower as the rendering resolution increases. – yms Dec 01 '11 at 17:40
  • @yms: the lowest possible value is --dpi 96. But it doesn't change anything. – duedl0r Dec 02 '11 at 08:34

3 Answers3

6

Your line is not missing, it is just too small to render on the screen.

This is because PDFs are rendered according to their page size, not according to how large the features on the page are. Everything on the page is scaled up or down to make it fit into the PDF page, and so your line is being scaled down and thus disappearing: 1 / 3 = 0.333 = no line.

To fix this you have the following options:

  1. Reduce the page size on wkhtml2pdf using: --page-size A4
  2. Reduce the width & height of the page exactly using: --page-width 9in --page-height 6in
  3. Make your line thicker.

Option 3 is probably preferable in this case. It's not a very elegant fix, but you don't have many options to play with. If you were writing the PDF on low-level then things could be done, but since you're using wkhtml2pdf then you are limited to what it allows you to set.

Alasdair
  • 13,348
  • 18
  • 82
  • 138
  • 1
    The bounty expired before the OP could manually award it to you. Unfortunately you didn't earn 2 or more upvotes, which would have at least awarded you half the bounty automatically. For more information: http://meta.stackexchange.com/a/16067/149052 – NullUserException Dec 10 '11 at 04:29
4

I had similar problem with borders of a table. What helped me was use of pt instead of px in my css.

See W3C:

But in general you would use a different set of units for display on screen than for printing on paper.

Ytus
  • 205
  • 1
  • 4
  • This did not help in my case. It did not help with @duedl0r example code. In my case 3px/3pt is a minimum border thickness that displays properly. – lng May 20 '14 at 09:04
  • Can you post a full answer with a reproducible code snippet? – VH-NZZ Nov 10 '15 at 23:59
  • In my case 1px instead of 0.3mm works, and 1pt works too. However 0.5pt disappears, so @Alasdair seems to be right in principle. – bpj Mar 11 '17 at 19:05
1

I'm assuming that you want thin line, or else you wouldn't have set the width to 1px.

The key to having thin, hairline borders displayed in PDFs made with wkhtmltopdf is to use SVG backgrounds like so:

.hairline-border {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'><rect x='0' y='0' width='100%' height='100%'  stroke='black' fill='white' stroke-opacity='1' /></svg>");
}

For a hairline separator (think <hr>), I use:

.hairline {
  height: 0.5mm;
  width: 100%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'><line x1='0mm' y1='0mm' x2='300mm' y2='0mm' style='stroke:black; stroke-width:0.25mm;' /></svg>");
}

and I use them like so:

<div class="hairline-border"></div>

And it's rendered correctly in Firefox and Safari/Chrome, and wkhtmltopdf at least keeps the line width as it is. There's been some discussion that a base64 transform of the SVG would warrant greater compatibility on IE. Frankly, I couldn't care less if IE is happy or not but see Inline SVG in CSS, if you must.

Community
  • 1
  • 1
VH-NZZ
  • 5,248
  • 4
  • 31
  • 47