Wie geht das: Druck von stark responsiven Webseiten über Browser-Druckfunktion oder über selbst erstellten Print-Button

  • Mit großem Interesse habe ich diesen Beitrag gelesen: Drucken von Beiträgen


    Leider bin ich in PHP JS usw. zu wenig gebildet, um zu verstehen, wie ich diese Anregungen in meinen neuen Websites umsetzen kann. Ich habe zwei alternative Ziele:

    Entweder soll über die Browser-Funktion gedruckt werden (bevorzugt) oder über einen selbst erstellten Druck-Button auf der Webseite.


    Meine J4 Websites sind mittels YooTheme Pagebuilder erstellt. Leider hat der Pagebuilder keine print.css – Nutzt man die Druckfunktion des Browsers, erhält man voll das Chaos. Aber immerhin kann man eine ansehnliche Ausgabe erhalten, wenn man an die URL der jeweiligen Seite ?tmpl=template anhängt. Und die darüber angezeigte Seite kann man schon relativ gut mit der Browser-Druckfunktion ausdrucken. Dabei wird offensichtlich überwiegend das Layout genutzt, das für große Screens gedacht ist.


    Da ein Webbrowser nicht von selbst auf die Idee kommt, mit der Druckfunktion zusammen die URL um ?tmpl=template zu ergänzen, benötige ich wohl einen Druck-Button, der dann nicht nur die zu druckende Seite in eine brauchbare Form bringt, sondern der dann auch zugleich die Druckfunktion des Browsers auslöst, damit der Besucher nicht zusätzlich noch den Druck-Button des Browsers betätigen muss.

    Frage: Wie muss der Code aussehen, den ich mit dem Button verknüpfe?


    Eine weitere Schwierigkeit:

    Meine Accordions sind bei Aufruf der Seite immer geschlossen. Und so wird der Copytext nicht mit ausgedruckt. Daher ich möchte eine CSS-Anweisung erstellen, die bei Nutzung der Print-Funktion bzw. bei Rendern der Webseite unter Anwendung von ?tmpl=template die Accordions allesamt ausklappen lässt. Auch da weiß ich nicht, wie ich das hinbekommen könnte.


    Natürlich habe ich schon beim YooTheme Support nachgefragt. Aber von dort kam bisher keine Antwort.


  • Leider hat der Pagebuilder keine print.css

    DIe ist auch eigentlich nicht nötig, als separate Datei. DU kannst in jedweder CSS-Datei, die geladen wird, z.B. custom.css einen Block einsetzen.


    Code
    @media print {
    
    
    }

    innerhalb dem du deine CSS-Anweisungen reinschiebst. Z.B. (Phantasie-Regeln):

    Code
    @media print {
     .dingsbums {
      display: none;
     }
     p {
      color: black;
     }
    }

    und die sind dann nur "wirksam", wenn du die Browser-Druckfunktion verwendest.


    Vielleicht ist so was ja schon drinnen in deiner jetzigen CSS-Datei?

  • Danke dir für deine Anregung! Inzwischen bin ich etwas weiter gekommen: Ich hab erkannt, dass die Ergänzung nach der URL nicht nötig ist. Ich kann ja das Logo in der print.css ausblenden. Dann bleibt aber am Ende des Drucks der Footer bestehen mit den von mir ja gewünschten Adress- und Kommunikationsdaten.


    Das Chaos im Layout beim Druck wird hauptsächlich verursacht durch die Blockquotes, die ich in manchen Seiten habe sowie durch die Accordions, die allesamt geschlossen sind, somit deren Text auf hidden steht und nix im Druck dargestellt werden kann. Die Blockquotes haben anscheinend keinen richtigen Container, sodass im Druck sich diese über oder unter den nachfolgenden Container schieben.


    Im YooTheme Pagebuilder habe ich die Möglichkeit, ganz bequem "Custom.css-Code" in ein Feld "Benutzerdefinierter Code" einzufügen. Und dann kann ich sofort die Wirkung der Änderung sehen. Durch Webrecherche und viel Ausprobieren habe ich aktuell die folgenden CSS-Definitionen erstellt:



    Betreffend der Blockquotes habe ich bereits versucht, diese als "display: block" anzulegen und diesen Block dann auch mit "clear: both" abzuschließen. Das hat aber nix gebracht. Und warum die internen Links immer noch in das Drucklayout eingefügt werden, weiß ich nicht.


    Die mir aktuell wichtigsten drei Dinge sind:

    • Wieso wird das Logo nicht auf der ersten Druckseite oben eingefügt?
    • Wie kann ich die Blockquotes so in der Webseite anlegen, dass sie auch im Druck als Container interpretiert werden?
    • Wie kann ich dafür sorgen, dass das Accordion beim Drucken alle items geöffnet hat?
  • Jetzt bin ich ein Stückchen weiter gekommen mit der Druckfunktion, weil ich aus dem Support-Forum von YooTheme neue Infos gefunden habe. Zu meinen Fragen kommt nun eine betreffend Javascript hinzu. Zunächst hier der Link zu der im YooTheme-Forum gegebenen Info (nur zum Nachlesen bei Interesse): https://yootheme.com/support/question/144981


    Gemäß dieser Info lege ich einen "Druck-Button" an, der die URL des zu druckenden Beitrags aufruft und an die URL anhängt:

    Code
    &print=1

    In den HTML-Code der Seite füge ich dann folgendes Script ein:

    Code
    <script>
    window.onload = function() { 
    printUrl = new URL(location.href).searchParams.get('print');
    if (printUrl) window.print(); 
    }
    </script>

    Damit habe ich erreicht, dass ich einen Druck-Button ins Seitenlayout einbinden kann, der die Druckfunktion des Browsers aufruft, wobei das Seitenlayout bis auf die bisher schon hier aufgezählten Fehler beibehält.


    Das Blockquote-Darstellungsproblem beim Drucken konnte ich lösen. Da hatte ich einen Denkfehler im HTML.


    Da jetzt sowieso schon Javascript ins Spiel kommt, könnte nun die JS-Funktion erweitert werden aber auch gleichzeitig eben in der print.css die noch erforderlichen Änderungen vorgenommen werden.


    Aktuell bestehen folgende Darstellungsprobleme beim Druck:

    • Accordions werden nicht automatisch alle ausgeklappt, damit deren Inhalt gedruckt wird
      ist evtl. nicht so einfach, da die Accordion-Funktion anscheinend teils in Javascript gelöst wurde und tiefer eingegriffen werden müsste.
    • Inhalts-Elemente, die breakpoint-abhängig gezeigt oder verborgen werden sollen, werden alle gleichzeitig angezeigt
      hierzu müsste der Seitenaufbau neu erfolgen und beim Abruf der Seite ein Smartphone im Hochformat simuliert werden. Evtl. per Javascript?

    Hat mir jemand dazu noch einen Tipp?


    Habe gerade vom YooTheme-Support betr. Accordion die Lösung bekommen. Auf diese CSS-Definitionen wäre ich wegen meiner geringen CSS-Kenntnisse nicht gekommen. In die @media print muss ich einfügen:


    CSS
    div.uk-accordion-content[hidden] {
        display: block !important;
        }

    Die Klasse  uk-accordion-content wird bei geschlossenem Accordion auf hidden gesetzt. Mit display: block wird das wieder aufgehoben. Warum vor der Klasse ein div steht, verstehe ich nicht. Aber es funktioniert!


    Vielleicht bekomme ich für die andere Frage ja auch noch eine Antwort von YooTheme. Ich halte euch hier auf dem Laufenden. Denn wer weiß, ob hier nicht auch paar Leute YooTheme Pagebuilder verwenden oder die CSS Definitionen nutzen können.


    Die JS-Print-Funktion oben geht so nicht, weil ein bloßes Neuladen der Webseite dazu führt, dass automatisch die Browser-Druckfunktion gestartet wird und an die ULR &print=1 angehängt wird.

    Ich verzichte auf den Button und das JS, wenn möglich.


    Betr. der Blockquote, die zum überlappenden Druck führt habe ich doch noch keine Lösung. Es war nur Zufall, dass die Seitenumbrüche auf der Testseite günstig lagen. Versuche, vor der Blockquote ein clear: both und danach display: block einzufügen und am Ende nochmals ein clear: both brachten keinen Erfolg.


    Vielleicht behebt sich der Ärger von selbst, wenn ich es erst mal schaffe, vom Layout für Smartphones im Portrait-Modus aus zu drucken.

    Einmal editiert, zuletzt von Indigo66 () aus folgendem Grund: 2 Beiträge von Clemens-XS mit diesem Beitrag zusammengefügt.

  • Indigo66 Danke für die Zusammenlegung. Das war mir noch gar nicht aufgefallen.

    Ich habe inzwischen an dem Thema "Ausdrucken von Webseiten möglichst in Original-Screendesign" heftig weiter gearbeitet und ich möchte die Ergebnisse hier teilen, damit alle was davon haben.


    Vorab: Generell führt die Nutzung eines Druck-Buttons in Verbindung mit URL-Ergänzungen wie &print=1 zu keiner besseren Darstellung des Layout, sondern verhindert lediglich, dass der Head und Footer sowie das Menü bei jeder Druckseite mit ausgegeben werden. Das von mir zitierte Script führt dazu, dass beim Neuladen der Seite in der das Script eingebettet ist, jedes Mal unerwünschter Weise der Druck aktiviert wird. Das Script ist also in dieser Form unbrauchbar. Ich nutze statt eines "Drcuk-Button" lieber die Druckfunktion des Browsers, zumal die meisten User das genau so machen würden. Alle Änderungen in der Druck-Darstellung definiere ich dann durch die "print.css" bzw. durch einen Abschnitt in der main.css mit der Media-Query @media print

    Bei mir liegt das Logo und die Navigation in einem Bereich mit der Klasse uk-navbar. Also brauche ich die bloß auf display: none setzen und das Problem ist gelöst. Erstaunlicher Weise wird der Footer ohne weitere Definition nur am Ende aller Seiten ein Mal gedruckt, genau wie gewünscht. Evtl. hat hier YooTheme Pagebuilder bereits eine @media print Regel eingebaut.


    Allerdings möchte ich schon, dass mein Logo auf der ersten Seite der Druckseiten erscheint. Dies habe ich versucht, mit folgender CSS-Definition zu erreichen:

    Code
    @media print {
        @page :first {
        content: url('/images/grafik/mein-logo.png');
        margin-bottom: 100pt;}
    }

    Aber das Logo erscheint nicht. @page :first kann nur für das Setzen von margins usw. verwendet werden und nicht für weitergehende Definitionen. Daher versuchte ich es noch mal wie folgt:

    CSS
    @media print {
    .cl-logo {
        content: url("https://meine-website.net/images/grafik/mein-logo.png");
        display: block;
    }
    @page :first {
        .cl-logo {
            display: block !important;}
    }

    Aber leider funzt auch das nicht und ich fand bis jetzt keine Lösung für das Einfügen des Logo nur im Kopf der ersten Seite. Vielleicht weiß hier jemand, wie ich das hinbekomme?


    Und nun zu den weiteren Herausforderungen:

    Das Hauptproblem liegt darin, dass die Browser hier scheinbar machen was sie wollen. Ich habe hier getestet mit Chrome / Brave, mit Firefox und mit Opera. Das beginnt bereits mit der Definition der Seitengröße eines DIN A4-Formats und deren Auswirkung auf das Rendern:

    Bei meinen Websites führt das dazu, dass mit Chrome und Opera ein ab 640px Breakpoint zweispaltig angelegter Text einspaltig dargestellt wird. Nur Firefox stellt den Text zweispaltig dar.


    Nun hätte ich gerne wenigstens dafür gesorgt, dass die Umbrüche das Layout nicht zerschießen. Eine ansprechend gestaltete Blockquote sollte nicht umgebrochen werden und ein Abschnitt in einem längeren Text möglichst auch nicht. Da ich ein Grid-Layout und kein Bootstrap verwende (YooTheme Pagebuilder) habe ich nach typischen CSS-Klassen gesucht, die ich dann mit page-break-inside: avoid; hindere, einen Umbruch durchzuführen. Jedes Mal wenn man eine "Section" in das Layout einfügt, wird die Klasse uk-container genutzt.

    Damit gelang es mir, die zusammengehörigen Inhalte weitgehend ohne unerwünschte Umbrüche zu drucken.


    Nun blieb noch der Fehler, dass die Zeilen eines Paragraph-Text bis ganz an den oberen oder unteren Seitenrand gedruckt wurden und zwar bei allen drei Browsern. Das sollte sich eigentlich mittels orphans und widows verhindern lassen. Diese Anweisungen wurden aber von allen drei Browsern ignoriert, obwohl caniuse.com zumindest Chrome und Opera besscheinigten, dass dies berücksichtigt wird. Firefox kann das bisher gar nicht. Auch das Einfügen von margin-top und margin-bottom brachte keine Verbesserung, wenn im Paragraph ein Umbruch erfolgt ist. Ansonsten aber wurde die Margin-Definition berücksichtigt.


    Ich beobachtete, dass zuweilen bei Firefox sogar innerhalb einer Überschrift (h1 in diesem Fall) ein Umbruch erfolgte, wodurch die recht große Schrift "in der Mitte geteilt" wurde, also die Oberlängen auf dem letzten Teil einer Seite und die Unterlängen auf der folgenden. Ich versuchte es mit

    Code
    h1, h2, h3 {
    page-break-after: avoid;
    }

    Aber Firefox kann bis jetzt avoid in Verbindung mit page-break-after oder page-break-before nicht berücksichtigen. Eigentlich sollte bei Firefox das Problem der zerrissenen Überschrift gar nicht auftreten, da die Überschrift ja zu Beginn eines Containers steht und der Container erst beendet wird, sobald der Paragraph-Text endet. Und page-break-inside soll ja angeblich von Firefox berücksichtigt werden. Tja, "sollte!" und "eigentlich"!


    Ein besonderes Problem ergibt sich, wenn ich den Druck von Bildern zulasse. Obwohl ich auch für Bilder in der print.css page-break-inside: avoid definiert habe und diese in der Regel Teil eines Containers sind, werden Bilder falsch positioniert oder zuweilen auch von Text überlappt. Da BIlder offensichtlich – zumindest in dem von mir genutzten Layout – Probleme bereiten und zudem wenig zusätzliche Information beinhalten, wenn sie mit ausgedruckt werden, habe ich Bilder generell in der print.css mit display: none unterdrückt. Leider bleibt der Platz, den die BIlder sonst benötigt hätten, als weiße Fläche im Ausdruck frei. Das stört natürlich gewaltig und führt wieder zu Papierverschwendung.


    Resultat bis jetzt also:

    • Das Logo im Kopf auf der ersten Druckseite konnte ich bis jetzt nicht einfügen.
    • Um eine weitere Optimierung speziell der Druckausgabe beim Firefox bemühe ich mich nicht mehr. In diesem Punkt ist das Teil einfach Schrott!
    • Ärgerlich ist, das die Definition für orphans und widows ignoriert wird, den das stört schon sehr in den Drucken.
    • Durch das Zusammen-Halten der Container-Bereiche werden bei allen Browsern leider die noch freien Bereiche einer Druckseite falsch berechnet und oftmals unnötiger Weise der nächste Container-Bereich schon auf der nächsten Druckseite gedruckt, statt in dem durchaus noch verfügbaren Platz auf der vorigen Seite. Dadurch wird Papier verschwendet und der Besucher verärgert.
    • Wenn ich den Druck von Bildern mit display: none verhindere, möchte ich eine Möglichkeit finden, dass der Platz, den die Bilder im Druck sonst eingenommen hätten, nicht frei gehalten wird.

    Ich würde mich freuen, wenn jemand mir für den ein oder anderen Punkt aus der obigen Aufzählung eine Lösung nennen würde!