CSS CSS Javascript Wasserzeichen

-Rayz-

Lieutenant
Registriert
Okt. 2010
Beiträge
897
Guten Morgen,

ich versuche momentan beim drucken ein Wasserzeichen für jede gedruckte Seite hinzuzufügen und das klappt noch nicht so recht.
Ziel ist es, dass Text + aktuellem Datum auf jeder neuen Seite als Wasserzeichen gedruckt wird. Dazu habe ich zwei Varianten getestet.

Diese zwei Varianten habe ich probiert.

HTML:
<div id="watermarked">
    <section>Content</section>
    <section>Content</section>
    <section>Content</section>
    <section>Content</section>
    <section>Content</section>
    ...
</div>


<section class="watermarked">Content</section>
<section class="watermarked">Content</section>
<section class="watermarked">Content</section>
<section class="watermarked">Content</section>
<section class="watermarked">Content</section>

Der CSS Code für die Variante mit der Klasse:

CSS:
.watermarked {
  position: relative;
  height: 100%;
  display: block;
  overflow: hidden;
}

.watermarked::after {
  position: absolute;
  height: 150%;
  width: 150%;
  z-index: 999;
  top: -50%;
  left: -50%;
  display: block;
  transform: rotate(-45deg);
  content: attr(data-watermark);
  opacity: 0.2;
  line-height: 4em;
  font-size: 16px;
  letter-spacing: 2px;
  color: #626161;
}

Hier ist natürlich das Problem, dass wenn der Content von mehreren sections auf eine Seite passt, ich auch das Wasserzeichen doppelt auf einer Seite habe. Stelle ich mein watermarked auf position fixed, dann überlappt es aber an einigen Stellen.

Javascript Code zum einfügen des Textes:

Javascript:
const options = {year: 'numeric', month: '2-digit', day: '2-digit'};
const now = new Date().toLocaleDateString('de-DE', options);
const elems = document.querySelectorAll('.watermarked');

elems.forEach(el => {
    // @ts-ignore
    el.dataset.watermark = 'Gültig bis ' + now;
    // @ts-ignore
    el.dataset.watermark = (el.dataset.watermark + ' ').repeat(200);

});

Eine weitere Variante die ich versuche, ist ein svg Bild zu erstellen und darüberzulegen. Das wäre dann einfach die HTML Variante mit dem Wasserzeichen als ID.

CSS:
CSS:
.content:before {
  content: "";
  position: absolute;
  z-index: 9999;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

Javascript:

Javascript:
const options = {year: 'numeric', month: '2-digit', day: '2-digit'};
const now = new Date().toLocaleDateString('de-DE', options);
document.getElementById('content').style.backgroundImage = 'url(data:image/svg+xml;utf8,<svg style="transform:rotate(-45deg)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 60"><text x="0" y="25" fill="%23000">gültig bis' + now + '</text></svg>) 0 0/100% 100vh';
Hier wird aber der Style gar nicht gesetzt und backgroundimage bleibt leer.

Über Hilfe wäre ich sehr dankbar.
 
Da tauchen dann die selben Probleme auf. Es ist ja nicht so, dass mein Wasserzeichen nicht auf jeder Seite abgebildet wird. Das ist schon vorhanden. Nur hab ich das Problem mit dem überlappen des Textes bei mehreren Seiten.
Deswegen wollte ich die Variante mit dem Backgroundimage probieren.
 
Geht es darum, das Wasserzeichen beim Drucken auf jeder Seite zu haben oder es explizit in jeder <section> zu haben?
Wenn du es absolut im <body> positionierst sollte es nur einmal pro Seite dargestellt werden und daher auch nicht überlappen.
 
Also es ist ja ein child vom body - wenn auch kein direktes aber es liegt über dem Content. Direkt an den Body komme ich so einfach nicht ran.
Bei position absolute taucht es nur einmal auf und ragt dann in die zweite Seite mit rein
 
Probiers mal mit position: fixed;
Ich hab mich hier mal mit dem Inspector gespielt, damit bekomme ich das Watermark auf allen Seiten einzeln

CSS - CSS Javascript Wasserzeichen _ ComputerBase Forum_Seite_2.jpgCSS - CSS Javascript Wasserzeichen _ ComputerBase Forum_Seite_3.jpgCSS - CSS Javascript Wasserzeichen _ ComputerBase Forum_Seite_4.jpgCSS - CSS Javascript Wasserzeichen _ ComputerBase Forum_Seite_5.jpg
 
Also am Problem ändert sich da bei mir leider nichts. Hier mal ein kleiner Ausschnitt wie es bei mir aussieht. Es überlappt und es geht auch nicht über die komplete Seite und bei der letzten Seite reicht es auch nicht bis runter.

Ich hab nun nach dem body die id angelegt und innerhalb.
HTML:
<body>
<app-root>
    <div id="printContent"  data-watermark="">
    </div>
</app-root>                                
</body>

CSS:
@media print {
  #printContent::after {
    position: fixed;
    z-index: 999;
    top: -50%;
    left: -50%;
    display: block;
    transform: rotate(-45deg);
    content: attr(data-watermark);
    opacity: 0.2;
    line-height: 4em;
    font-size: 16px;
    letter-spacing: 2px;
    color: #626161;
  }
}

Mit top, left width und height teste ich schon die ganze Zeit rum aber bei position fixed ist immer diese Überlappung vom Text.
 

Anhänge

  • druck.JPG
    druck.JPG
    24,5 KB · Aufrufe: 283
Ich denke das hat mit dem transform und der top/left Positionierung zu tun. Mit top/left verschiebst du das Element ja nach links oben.
Lass dir das Watermark mal in der normalen Ansicht anzeigen (formatting raus aus der media query oder im Inspector media type print emulieren) und spiel dich mit der Positionierung und vielleicht mit transform-origin.
 
Nun gut ich brauch aber die Position um 45° versetzt. Deswegen hatte ich ja versucht das ganze als svg overlay zu integrieren - was aber bisher noch nicht so recht funktioniert

Aber auch so:
position: fixed;
z-index: 999;
display: block;
content: attr(data-watermark);
top: 0;
left: 0;
opacity: 0.2;
line-height: 4em;
font-size: 16px;
letter-spacing: 2px;
color: #626161;

geht es über die Seiten hinaus und kollidiert
 
Ich kann das auf deinem Bild schlecht erkennen: Ist der Text so lang oder wiederholt er sich? Falls er sich wiederholt kannst du das Watermark einfach in einen weitere Container packen in dem du overflow: hidden; setzt, damit "bleeded" das Watermark nicht auf die angrenzenden Seiten.
 
Bei position fixed sieht es so aus:
ich hab davor nun einen container mit overflow hidden.
HTML:
<body>
    <app-root>
        <div class="wrapper">
            <div id="printContent">
                <section></section>
                <section></section>
                <section></section>
                <section></section>
                <section></section>
                ...
            </div>
        </div>
    </app-root>
</body>


Mit position absolute sieht es zwar besser aus aber es geht nicht komplett über die letzte Seite und das Problem wird größer, sobald ich transform wieder reinnehme
 

Anhänge

  • druck_2.JPG
    druck_2.JPG
    81 KB · Aufrufe: 249
Dass es nicht komplett über die letzte Seite geht liegt wahrscheinlich daran, dass entweder <app-root> oder der Wrapper auf der letzten Seite wegen dem Content auch nicht bis nach unten gehen. Damti bräuchtest du für das Watermark wieder einen Container direkt im body (wobei auch nicht gesagt ist, dass der auf der letzten Seite bis nach unten geht).
Da bleibt dir wohl nur die Spielerei mit dem Inspector bis es halbwegs OK aussieht. Noch ein Tipp wegen abgeschnittenen Elementen: page-break-inside: avoid;
 
Komme da auf keinen grünen Zweig, ob position fixed oder absolute - trotz wrapper drumherum mit overflow hidden geht das Wasserzeichen in andere Seiten über.
 
Lass dir im Wrapper einmal eine Border anzeigen und schau, ob die auch auf die anderen Seiten überfließt.
Hat der Wrapper 100% height? Letztlich kann es leider auch vorkommen, dass Browser beim Rendering für Ausdrucke unterschiedlich arbeiten.
 
Der Wrapper geht über den Kompletten Inhalt und hört dann auch direkt wieder auf sobald kein Inhalt mehr da ist. Sprich er geht über mehrere Seiten.

.wrapper {
overflow: hidden;
width: 100%;
height: 100%;
border: 2px solid #000000;
}

Auf der letzten SEite wo der Wrapper dann mittig aufhört, ist das Wasserzeichen aber dennoch darüberliegend zu sehen...
 
Es gibt kein after mehr. Ich hab versucht es als Overlay darüberzulegen:

HTML:
<body>
    <app-root>
        <div class="wrapper">
              <div id="watermarked"></div>
        </div>
        <div id="printContent">
            <section></section>
            <section></section>
            <section></section>
            <section></section>
            <section></section>
            ...
        </div>
    </app-root>
</body>

Ich muss den Wrapper auf position relative setzen damit das mit dem overflow funktioniert. Dadurch wird der Wrapper als eigene Seite gesehen..

CSS:
@media print {
  #watermarked {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    z-index: 0;
    transform: rotate(-45deg);
    background-color: #ffff00;
    width: 100%;
  }

  .wrapper {
    overflow: hidden;
    width: 100%;
    height: 100vh;
    position: relative;
    border: 2px solid #000000;
  }
}



.. muss den wrapper ja nur absolute setzen...
 
So sieht es nun aus. Allerdings nur für Seite 1.
Das ist aber kein Problem denke ich, aus der ID mache ich eine Klasse und setze die Klasse + Wrapper an jede Content-Seite dran. Dann sollte es denke ich gehen.

CSS:
CSS:
@page { margin: 2cm }
@media print {
  #watermarked {
    position: absolute;
    top: -25%;
    left: -20%;
    height: 170vh;
    z-index: 0;
    letter-spacing: 2px;
    line-height: 45px;
    font-size: 16px;
    transform: rotate(-45deg);
    background-color: #ffff00;
    width: 200%;
  }

  .wrapper {
    overflow: hidden;
    width: 100%;
    height: 100%;
    position: absolute;
    border: 2px solid #000000;
  }
  html, body {
    background-color: #ffffff !important;
    width: 210mm;
    height: 297mm;
  }
}
 

Anhänge

  • druck_3.JPG
    druck_3.JPG
    241,7 KB · Aufrufe: 250
Zurück
Oben