Wie funktioniert die CSS-Drucklogik bei der Umwandlung von HTML in PDF?
8 Min. Lesezeit
Wenn Sie eine Webseite in ein PDF umwandeln, erhalten Sie ein anderes Ergebnis als das, was Sie auf dem Bildschirm sehen – und das ist kein Fehler, sondern die natürliche Folge des Übergangs zwischen zwei verschiedenen Layoutmodellen. In diesem Beitrag erklären wir, wie Webseiten in Seiten zerlegt werden, welche Druckregeln CSS bereithält und warum dynamische Inhalte Probleme bereiten.
Zwei Layoutmodelle
Eine Webseite ist ein fließendes (kontinuierliches) Medium. Es gibt keinen Seitenbegriff; der Inhalt fließt von oben nach unten als endlose Spalte. Die Breite richtet sich nach dem Browserfenster, und das Layout passt sich daran an.
PDF ist ein seitenbasiertes (paged) Medium. Es gibt Seiten fester Größe, und der Inhalt wird auf sie verteilt.
CSS unterscheidet beide über den Begriff des "Medientyps" und erlaubt die Anwendung unterschiedlicher Regeln.
@media print: zwei verschiedene Stilsätze
Webseiten können für Bildschirm und Druck unterschiedliche Stile definieren:
/* Für alle */
body { font-family: sans-serif; }
/* Nur am Bildschirm */
@media screen {
nav { position: fixed; background: #222; }
}
/* Nur im Druck */
@media print {
nav, .sidebar, .werbung, .kommentare { display: none; }
body { font-size: 11pt; color: #000; background: #fff; }
a { text-decoration: underline; }
}
Die PDF-Erzeugung nutzt die print-Regeln. Bei gut gestalteten Websites bewirkt das eine deutliche Bereinigung der Ausgabe:
- Navigationsmenüs, Seitenleisten und Werbung werden ausgeblendet.
- Die Farben werden einfach und gut lesbar.
- Schriftgrößen werden in Punkt angegeben.
Doch es entstehen auch zwei Arten von Problemen:
Zu viel Ausblendung. Manche Websites blenden im Druckstil auch wichtige Infokästen aus.
Gar kein Stil. Websites ohne definierten Druckstil verwenden das Bildschirmlayout unverändert, und das Ergebnis ist meist schlecht – fest positionierte Menüs können sich auf jeder Seite wiederholen, dunkle Hintergründe können Probleme bereiten.
Die physische Entsprechung von CSS-Einheiten
Im Druckkontext haben CSS-Einheiten exakte physische Werte:
| Einheit | Physische Entsprechung | |---|---| | 1in (Zoll) | 2,54 cm | | 1cm | 1 cm | | 1mm | 1 mm | | 1pt (Punkt) | 1/72 Zoll | | 1pc (Pica) | 12 Punkt | | 1px (CSS-Pixel) | 1/96 Zoll |
Die letzte Zeile ist entscheidend: 96 CSS-Pixel sind genau 1 Zoll.
Die Folge dieser Konstante: Eine A4-Seite (210 mm = 8,27 Zoll Breite) ist ohne Abzug der Ränder etwa 794 CSS-Pixel breit.
Und das hat bei responsiven Layouts einen erheblichen Effekt. Viele Websites verwenden Umbruchpunkte wie diese:
@media (max-width: 768px) { /* Tablet- und Mobil-Layout */ }
@media (max-width: 1024px) { /* Layout für kleine Bildschirme */ }
794 Pixel liegen unter der zweiten Regel und auf manchen Websites auch nahe an der ersten. Das Ergebnis: Im PDF wechselt die Seite in ein anderes Layout als das, was Sie am Desktop sehen – Spalten rutschen untereinander, das Menü wird zum Hamburger-Symbol, Bilder nehmen die volle Breite ein.
Das ist die Antwort auf die Frage: "Warum sieht die Seite im PDF aus wie auf dem Handy?"
Lösungswege: Querformat verwenden (A4 quer entspricht ca. 1123 Pixeln), die Ränder verkleinern oder eine Skalierung anwenden.
@page: die Seite selbst definieren
In CSS definiert die Regel @page die Seitenbox:
@page {
size: A4;
margin: 2cm 1.5cm;
}
Für size lassen sich vorgegebene Größen (A4, A3, Letter, Legal) oder eigene Maße (size: 210mm 297mm) verwenden. Das Schlüsselwort landscape ändert die Ausrichtung.
Über Pseudoklassen lassen sich für verschiedene Seiten unterschiedliche Regeln anwenden:
@page :first {
margin-top: 5cm; /* Abstand oben auf der Titelseite */
}
@page :left {
margin-left: 3cm; /* Bundsteg */
}
@page :right {
margin-right: 3cm;
}
Das wird bei beidseitigen Ausgaben im Buchstil verwendet, um Platz für die Bindung zu lassen.
Der Seitenumbruchalgorithmus
Der Inhaltsfluss wird in Abschnitte von Seitenhöhe zerlegt. Fällt die Umbruchstelle mitten in ein Element, muss der Browser eine Entscheidung treffen.
CSS bietet Eigenschaften, die diese Entscheidung steuern:
/* Dieses Element soll nicht geteilt werden */
table, figure, .karte { page-break-inside: avoid; }
/* Vor diesem Element soll eine neue Seite beginnen */
h1, .kapitel { page-break-before: always; }
/* Unmittelbar nach diesem Element soll kein Umbruch erfolgen */
h2, h3 { page-break-after: avoid; }
Die dritte Regel ist besonders nützlich: Sie verhindert, dass eine Überschrift allein am Seitenende steht (und der zugehörige Text erst auf der nächsten Seite folgt).
Kontrolle von Schusterjungen und Hurenkindern:
p {
orphans: 3; /* am Seitenende sollen mindestens 3 Zeilen eines Absatzes stehen */
widows: 3; /* am Seitenanfang sollen mindestens 3 Zeilen stehen */
}
Das sind klassische Regeln der Typografie: Eine einzelne Zeile eines Absatzes, die allein am Seitenende oder am Seitenanfang steht, sieht schlecht aus.
Umbruchverhalten nach Elementtyp:
| Element | Umbruchverhalten | |---|---| | Textblock | Wird an Zeilengrenzen umbrochen | | Tabelle | Wird an Zeilengrenzen umbrochen | | Bild | Nicht teilbar; rutscht oder wird abgeschnitten | | Positioniertes Element | Unvorhersehbare Ergebnisse | | Flexbox / Grid | Unterstützung je nach Browser unterschiedlich |
Die letzten beiden Zeilen sind wichtig: Absolute Positionierung und moderne Layoutsysteme verhalten sich im Druckkontext nicht immer gut. Ein komplexes Grid-Layout kann an einer Seitengrenze unerwartet auseinanderfallen.
Warum Hintergrundgrafiken nicht gedruckt werden
Druck-Engines drucken Hintergrundfarben und -bilder standardmäßig nicht. Das ist ein eingebautes Verhalten zur Tintenersparnis.
In CSS gibt es einen Weg, das zu erzwingen:
* {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
Auch im Druckdialog des Browsers findet sich die Option "Hintergrundgrafiken".
Ist diese Einstellung deaktiviert, werden Designs mit dunklem Hintergrund zur Katastrophe: Weißer Text auf schwarzem Grund wird, wenn der Grund nicht gedruckt wird, zu Weiß auf Weiß, und nichts ist mehr sichtbar.
Wenn Sie Ihr HTML selbst erstellen, ist es der sicherere Ansatz, die Farben im Druckstil umzukehren:
@media print {
.dunkler-bereich { background: #fff; color: #000; }
}
Links und Interaktion
Hyperlinks werden meist in PDF-Linkanmerkungen umgewandelt und bleiben anklickbar. Das hängt von den Fähigkeiten des Konverters ab.
In einem gedruckten Dokument ist nicht sichtbar, wohin ein Link führt. Mit CSS lässt sich die Adresse in den Text einfügen:
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #555;
}
}
Formularfelder werden in der Regel zu ihrer statischen Darstellung. Manche Konverter können HTML-Formulare in PDF-Formularfelder umwandeln, doch das ist keine verbreitete Fähigkeit.
JavaScript-Interaktionen gehen vollständig verloren: Aufklappmenüs, Reiter, Akkordeons. Inhalte im geschlossenen Zustand erscheinen im PDF überhaupt nicht – ist ein FAQ-Bereich als Akkordeon aufgebaut, sind im PDF nur die Fragen sichtbar, nicht die Antworten.
Für diesen Fall müssen versteckte Inhalte im Druckstil geöffnet werden:
@media print {
.akkordeon-inhalt { display: block !important; }
}
Dynamische Inhalte und das Zeitproblem
Die meisten modernen Webseiten laden ihre Inhalte nach dem Seitenaufbau nach: API-Aufrufe, verzögert geladene Bilder, unendliches Scrollen.
Der Konverter betrachtet die Seite ab einem bestimmten Punkt als "fertig" und startet die PDF-Erzeugung. Zur Bestimmung dieses Punktes kommen verschiedene Strategien zum Einsatz:
- Load-Ereignis: Sobald die ersten Ressourcen der Seite geladen sind. Meist unzureichend.
- Netzwerkruhe (Network Idle): Wenn eine bestimmte Zeit lang keine neue Anfrage eintrifft. Ein besseres Signal.
- Feste Wartezeit: Etwa drei Sekunden warten. Grob, aber einfach.
- Auf ein Element warten: Warten, bis ein bestimmter CSS-Selektor erscheint. Die zuverlässigste Methode, erfordert aber Konfiguration.
Bei Seiten mit unendlichem Scrollen kann keine Strategie den vollständigen Inhalt liefern – der Inhalt lädt nur, während der Nutzer scrollt, und der Konverter scrollt nicht.
Verzögert geladene Bilder (Lazy Loading) haben dasselbe Problem: Bilder, die nicht in den Sichtbereich gelangen, werden nie geladen und bleiben im PDF leer.
Das Laden von Schriftarten
Webschriften werden von externen Quellen heruntergeladen:
@font-face {
font-family: 'Speziell';
src: url('https://fonts.example.com/speziell.woff2');
}
Kann die Umwandlungsumgebung diese Quelle nicht erreichen, wird die Schrift nicht geladen und der Browser fällt auf eine Ersatzschrift zurück. Weil sich die Zeichenbreiten ändern, verschiebt sich das Layout.
Zudem gibt es ein Zeitproblem: Wird das PDF erzeugt, bevor die Schrift geladen ist, wird die Seite mit der Ersatzschrift gezeichnet.
Lösungen für kritische Dokumente:
- Die Schrift als base64 in das CSS einbetten.
- Systemschriften verwenden.
- Eine Prüfung einbauen, die auf das Laden der Schrift wartet.
Zusammengefasst
Die Umwandlung von HTML in PDF ist der Übergang von einem fließenden zu einem seitenbasierten Medium, und CSS steuert diesen Übergang über @media print, @page und die Seitenumbrucheigenschaften. Weil das CSS-Pixel als 1/96 Zoll definiert ist, wird eine A4-Seite etwa 794 Pixel breit, was responsive Layouts in die mobile Darstellung wechseln lässt. Hintergrundgrafiken werden standardmäßig nicht gedruckt; bei Designs mit dunklem Hintergrund ist das ein ernstes Problem. Umbruchentscheidungen lassen sich über Eigenschaften wie page-break-inside, orphans und widows steuern, doch diese Regeln müssen im Code der Seite selbst definiert sein. Und dynamische Inhalte können unvollständig ankommen, je nachdem, wann der Konverter die Seite für "fertig" hält – bei Seiten mit unendlichem Scrollen und Lazy Loading ist es meist unmöglich, den vollständigen Inhalt zu erhalten.
Häufig gestellte Fragen
Welchem physischen Maß entspricht ein Pixel in CSS?
Im Druckkontext ist das CSS-Pixel als 1/96 Zoll definiert. 96 Pixel ergeben also genau 1 Zoll, rund 2,54 Zentimeter. Dank dieser Konstante ist eine A4-Seite (210 mm Breite) etwa 794 CSS-Pixel breit. Genau deshalb wechseln responsive Layouts im PDF in die mobile Darstellung – 794 Pixel liegen auf vielen Websites unterhalb des Umbruchpunkts für Tablet oder Mobilgerät.
Was bewirkt die @page-Regel?
Sie definiert die Seite selbst: Größe, Ausrichtung und Ränder. Die Regel @page { size: A4 landscape; margin: 1.5cm; } sorgt beispielsweise dafür, dass die Ausgabe im A4-Querformat erfolgt und an jeder Kante 1,5 cm Rand bleibt. Über die Pseudoklassen :first, :left und :right lassen sich zudem für die erste Seite oder für ungerade und gerade Seiten unterschiedliche Regeln anwenden.
Wie entscheidet der Seitenumbruchalgorithmus?
Der Inhaltsfluss wird in Abschnitte von Seitenhöhe zerlegt. Fällt die Umbruchstelle mitten in ein Element, prüft der Browser zuerst die Seitenumbrucheigenschaften (etwa page-break-inside); gibt es keine Einschränkung, teilt er das Element. Textblöcke werden an Zeilengrenzen umbrochen, Tabellen an Zeilengrenzen; Bilder lassen sich nicht teilen und rutschen daher entweder ganz auf die nächste Seite oder werden abgeschnitten.
Warum gelangen per JavaScript erzeugte Inhalte manchmal nicht ins PDF?
Weil der Konverter die Seite ab einem bestimmten Punkt als 'fertig' betrachtet und die PDF-Erzeugung startet. Kommt der Inhalt erst nach dem Laden der Seite über eigene Netzwerkanfragen und wartet der Konverter nicht lange genug, entsteht die Ausgabe, bevor diese Anfragen abgeschlossen sind. Manche Werkzeuge warten, bis der Netzwerkverkehr zum Stillstand kommt, doch bei Seiten mit unendlichem Scrollen oder periodischer Aktualisierung tritt dieser Zustand nie ein.
Probieren Sie es gleich mit HTML/URL → PDF aus.
HTML/URL → PDF ausprobieren