Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Images

Images can be embedded with <img> and with the CSS background-image.

Supported formatsPNG, JPEG, WebP
What src may containA local relative or absolute path, an http(s) URL, or a data: URI

SVG and GIF are not supported.

<img>

<img src="logo.png" width="120">
<img src="https://example.com/chart.png" alt="Sales over time">
<img src="data:image/png;base64,iVBORw0…">
  • An <img> sits on the line as an inline replaced element. Give it display: block to put it on a line of its own
  • The width and height attributes and the CSS width and height are both honoured. With neither, the intrinsic size is used; with only one, the other is derived while keeping the aspect ratio
  • An image that cannot be fetched or decoded leaves just that element empty; it does not stop the document from being produced. Pass --load-media-error-handling abort to stop instead
  • However many times the same image is used, it is fetched, decoded, and embedded once

object-fit and object-position

These control how the image is fitted into the box you give it.

img.thumb {
  width: 120px;
  height: 80px;
  object-fit: cover;          /* fill | contain | cover | none | scale-down */
  object-position: 50% 50%;
}

Background images

.watermark {
  background-image: url("stamp.png");
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
}

Only url() is accepted in background-image. Gradient functions such as linear-gradient() and comma separated multiple backgrounds are not supported. By default the image is tiled at its intrinsic size.

When border-radius is combined with a background image, the image is not clipped to the rounded corners; the radius applies only to the background colour.

Fetching remote images

This is off by default. Turn it on explicitly with --allow-remote-assets.

sghtmltopdf report.html --allow-remote-assets

Even when enabled, requests to destinations that are not globally reachable are always blocked. The rule is to allow only global unicast; the following are rejected.

KindRanges
Loopback127.0.0.0/8, ::1
Private10/8, 172.16/12, 192.168/16, fc00::/7
Link-local169.254/16 (including the cloud metadata endpoint 169.254.169.254), fe80::/10
CGNAT100.64.0.0/10 (cloud-internal load balancers and the like)
Other non-global0.0.0.0/8, 192.0.0.0/24, 198.18.0.0/15, 240.0.0.0/4, multicast, documentation
IPv6 special-purposeTeredo 2001::/32, 2001:db8::/32, ORCHIDv2 2001:20::/28, 100::/64

IPv6 forms that embed an IPv4 address (IPv4-mapped ::ffff:a.b.c.d, IPv4-compatible ::a.b.c.d, NAT64 64:ff9b::/96, 6to4 2002::/16) are judged by the embedded IPv4 address. Letting them through would allow the IPv4 filter to be bypassed.

The check is applied to the result of name resolution, so DNS rebinding and redirect-based bypasses are prevented by the same mechanism.

Private

Ranges

sghtmltopdf untrusted.html --allow /var/app/assets

JPEG is embedded as is

JPEG images are not decoded. Only their dimensions are read, and the data goes into the PDF unchanged, as DCTDecode. Nothing is re-encoded, so quality is preserved and conversion is faster.

The trade-off is that --grayscale leaves JPEG and CMYK images in colour, since there is no decoder for them. If you need them in greyscale, convert the images before rendering.

PNG and WebP are fully decoded, and an alpha channel is carried through as transparency.

Loading no images at all

sghtmltopdf invoice.html --no-images

This stops both <img> and the CSS background-image from being loaded.