Custom Popups Erstellen

Custom Popups Erstellen

Custom Activation Pop-up (HTML & CSS) – Anleitung

Überblick

Für Activation Pop-ups bieten wir eine Custom-Pop-up-Funktion, bei der Kund:innen das Pop-up frei über eigenes HTML und CSS gestalten können.
Uptain stellt dafür ein HTML-Grundgerüst und Beispiel-CSS bereit, das als Ausgangspunkt dient und individuell angepasst werden kann.

Typische Use Cases:

  • Voucher-/Gutschein-Pop-up

  • Abbruch-/Exit-Intent Pop-up

  • Aktivierung eines Rabattcodes per Klick oder automatisch


Wie funktioniert das Custom Pop-up?

Das Pop-up besteht aus:

  1. HTML-Struktur

    • definiert die Inhalte (z. B. Gutschein-Code, Buttons, Text, Close-Icon)

  2. CSS / Styling

    • bestimmt Layout, Größe, Position, Hintergrundbild etc.

    • responsive über Breakpoints (Mobile / Tablet / Desktop)

  3. Dynamische Inhalte

    • können per Platzhalter eingebunden werden (z. B. {{voucherCode}})

0) Wichtige Einstellungen & Trigger (vor dem Start)

Bevor das Custom Pop-up gestaltet wird, sollten die wichtigsten Einstellungen korrekt gewählt werden, da diese maßgeblich beeinflussen, wann und wie das Pop-up ausgespielt wird.

Regain Type (Tracking-Logik)
Bestimmt, wann ein Erfolg (Regain) gezählt wird:

  • Voucher: Regain wird nur gezählt, wenn der Gutschein tatsächlich eingelöst wird (empfohlen für Gutschein-Pop-ups)

  • Shown: Regain wird bereits beim Anzeigen des Pop-ups gezählt

  • Manual: Regain wird erst nach einer aktiven Nutzerinteraktion gezählt (z. B. Klick auf ein Element)

Trigger (Ausspielung des Pop-ups)
Definiert, wann das Pop-up erscheint:

  • Desktop: empfohlen sind MouseOutV2 und Tab Idle

  • Mobile: empfohlen sind TapIdle (kein klassischer Mouse-Out verfügbar)

  • Weitere Trigger sollten nur gezielt eingesetzt werden, um zu häufige oder unpassende Ausspielungen zu vermeiden

Fallback Trigger
Optional – kann leer bleiben oder ebenfalls auf MouseOutV2 gesetzt werden.

Blocking Time
Kann leer bleiben (Standardverhalten). Wird genutzt, um zu verhindern, dass Nutzer das Pop-up zu häufig sehen.

Template-Referenzen (z. B. Activation Mail Template)
Diese Felder sind für Custom Pop-ups in der Regel nicht relevant und können leer bleiben.

💡 Best Practice:
Für klassische Gutschein-Pop-ups empfiehlt sich:

  • Regain Type: Voucher

  • Desktop Trigger: Mouse Out V2 + Tab Idle

  • Mobile Trigger: Tap Idle

1) HTML – Grundstruktur

Das folgende HTML wird im Custom-Pop-up hinterlegt:

<div class="__up_activation"> <div id="__up_pop_bg" class="__up_background __up_hidden" data-up-close-event="background"></div> <div class="__up_pop __up_hidden __up_visible"> <button type="button" class="__up_close __up_close_button __up_close_icon" data-up-close-event="close-x">×</button> <div class="__up_action"> <input type="text" class="__up_code_value" value="{{voucherCode}}"> </div> </div> </div>

Wichtige Bestandteile

  • __up_pop_bg
    → Background/Overlay (dunkler Hintergrund), wird ebenfalls fürs Schließen genutzt.

  • __up_pop
    → Container des eigentlichen Pop-ups.

  • Close Button
    → Schließt das Pop-up (über data-up-close-event="close-x").

  • {{voucherCode}}
    → Dynamischer Gutschein-Code (Platzhalter wird von Uptain gefüllt).

    • Sollte kein Code Vorhanden sein kann die gesamte Code Linie entfernt werden

Hinweis: Die CSS-Klassen sind notwendig, damit Uptain die Elemente korrekt erkennt und steuern kann.


2) CSS – Beispiel-Styling

Wir stellen Beispiel-CSS bereit, das Kund:innen verwenden und anpassen können.
Das Styling nutzt mehrere Variablen, um Anpassungen einfacher zu machen.

A) Muss-Anpassungen (sehr wichtig)

✅ 1. Hintergrundbild ersetzen

In den Variablen:

@popupWidthMobile: 375px; @popupWidthTablet: 440px; @popupWidthDesktop: 450px; @popupHeightMobile: 246px; @popupHeightTablet: 295px; @popupHeightDesktop: 295px; @backgroundImageDesktop: url('https://test.de/Zwischenablage5.jpg?ts=1740392776'); @backgroundImageMobile: url('https://test.de/Zwischenablage5.jpg?ts=1740392776'); @codeTopOffsetMobile: 132px; @codeTopOffsetTablet: 162px; @codeTopOffsetDesktop: 162px; @codeLeftOffsetMobile: 20px; @codeLeftOffsetTablet: 20px; @codeLeftOffsetDesktop: 25px; @codeMaxWidthMobile: 195px; @codeMaxWidthTablet: 195px; @codeMaxWidthDesktop: 195px; @codeFontSizeMobile: 16px; @codeFontSizeTablet: 16px; @codeFontSizeDesktop: 16px; @codeLineHeightMobile: 16px; @codeLineHeightTablet: 16px; @codeLineHeightDesktop: 16px; @codeFontColor: #555; @codePlaceholderColor: #555; @closeButtonSize: 24px; @closeButtonTopOffsetMobile: 12px; @closeButtonTopOffsetTablet: 14px; @closeButtonTopOffsetDesktop: 14px; @closeButtonRightOffsetMobile: 12px; @closeButtonRightOffsetTablet: 14px; @closeButtonRightOffsetDesktop: 14px; @closeButtonColor: #333; .__up_pop_bg { position: fixed; top: 0; left: 0; opacity: 0; visibility: hidden; width: 100%; height: 100%; z-index:9998; background-color:rgba(0,0,0,0.7); transition:visibility .5s, opacity .75s linear; } .__up_pop_bg.__up_visible{ opacity:1; visibility:visible; pointer-events:auto; } .__up_pop { width: @popupWidthMobile; height: @popupHeightMobile; position: fixed; left: 50%; top: 50%; transform: translateX(0); -webkit-transform: translateX(0); z-index: 10000; } .__up_pop.__up_visible { animation-duration: .5s; -webkit-animation-name: open-pop; animation-name: open-pop; -webkit-animation-fill-mode: both; animation-fill-mode: both; animation-delay: 0s } .__up_pop:before { content: ''; display: block; position: relative; width: 100%; height: 100%; background-image: @backgroundImageMobile; background-size: cover; background-position: bottom center; background-repeat: no-repeat; } @media screen and (min-width: 440px) { .__up_pop { width: @popupWidthTablet; height: @popupHeightTablet; } } @media screen and (min-width: 756px) { .__up_pop { width: @popupWidthDesktop; height: @popupHeightDesktop; } .__up_pop:before { position: absolute; background-image: @backgroundImageDesktop; background-position: center left; } } .__up_action { position: absolute; text-align: left; max-width: @codeMaxWidthMobile; left: @codeLeftOffsetMobile; top: @codeTopOffsetMobile; width: 100%; display: flex; align-items: stretch; justify-content: space-between; } @media screen and (min-width: 440px) { .__up_action { top: @codeTopOffsetTablet; transform: translateX(0); left: @codeLeftOffsetTablet; max-width: @codeMaxWidthTablet; } } @media screen and (min-width: 756px) { .__up_action { top: @codeTopOffsetDesktop; left: @codeLeftOffsetDesktop; max-width: @codeMaxWidthDesktop; } } .__up_pop input::-webkit-input-placeholder { color: @codePlaceholderColor; } .__up_pop input:-moz-placeholder { color: @codePlaceholderColor; } .__up_pop input::-moz-placeholder { color: @codePlaceholderColor; } .__up_pop input:-ms-input-placeholder { color: @codePlaceholderColor; } .__up_action_button { background: #c0bc69; border: 0; border-radius: 0 4px 4px 0; color: #fff; padding: 0 16px; cursor: pointer; transition: all 300ms ease; } input.__up_code_value { background: none; border: none; box-shadow: none; border-radius: 4px 0 0 4px; width: 100%; color: @codeFontColor; box-sizing: border-box; transition: all 300ms ease; line-height: @codeLineHeightMobile; font-size: @codeFontSizeMobile; padding: 12px 8px 12px 16px; border-right: 0; position: relative; } @media screen and (min-width: 440px) { input.__up_code_value { line-height: @codeLineHeightTablet; font-size: @codeFontSizeTablet; } } @media screen and (min-width: 756px) { input.__up_code_value { line-height: @codeLineHeightDesktop; font-size: @codeFontSizeDesktop; } } input.__up_code_value:focus-visible { outline: #eee; } input.__up_code_value.__up_code_input_copied { border-color: #c0bc69; } input.__up_code_value.__up_code_input_copied + .__up_action_button { text-shadow: 1px 1px 2px #e1e0b4; } .__up_close_button { position: absolute; right: @closeButtonRightOffsetMobile; top: @closeButtonTopOffsetMobile; color: @closeButtonColor; background: none; border: none; font-size: @closeButtonSize; line-height: @closeButtonSize; padding: 0; z-index: 1; transition: all 300ms ease; cursor: pointer; } @media screen and (min-width: 440px) { .__up_close_button { right: @closeButtonRightOffsetTablet; top: @closeButtonTopOffsetTablet; } } @media screen and (min-width: 756px) { .__up_close_button { right: @closeButtonRightOffsetDesktop; top: @closeButtonTopOffsetDesktop; } } .__up_close_button:hover { transform: scale(1.15); } @keyframes open-pop { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0); -webkit-transform: translate(-50%, -50%) scale(0) } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); -webkit-transform: translate(-50%, -50%) scale(1) } } @keyframes close-pop { 0% { opacity: 1; transform: translate(-50%, -50%) scale(1); -webkit-transform: translate(-50%, -50%) scale(1) } 100% { opacity: 0; transform: translate(-50%, -50%) scale(0); -webkit-transform: translate(-50%, -50%) scale(0) } }

A) Muss-Anpassungen (sehr wichtig)

✅ 1. Hintergrundbild ersetzen

In den Variablen:

@backgroundImageDesktop: url('https://.../bild.jpg'); @backgroundImageMobile: url('https://.../bild.jpg');

➡ Kund:innen müssen diese URLs unbedingt ersetzen, wenn sie ein eigenes Hintergrundbild nutzen möchten.

Tipp:

  • Desktop: Querformat / größere Auflösung

  • Mobile: optimiertes Bild für Mobile (z. B. kürzerer Fokus, besserer Crop)


✅ 2. Pop-up-Größe prüfen und ggf. anpassen

Die Default-Werte sind:

@popupWidthMobile: 375px; @popupWidthTablet: 440px; @popupWidthDesktop: 450px; @popupHeightMobile: 246px; @popupHeightTablet: 295px; @popupHeightDesktop: 295px;

➡ Kund:innen sollten diese Werte überprüfen, wenn:

  • das Hintergrundbild andere Maße hat

  • Inhalte abgeschnitten werden

  • Buttons/Inputs nicht passen


B) Inhalt positionieren (Gutschein-Code / Elemente)

Der Bereich .__up_action ist das Element, das den Gutschein-Code enthält.

Positionierung erfolgt über:

@codeTopOffsetMobile: 132px; @codeTopOffsetTablet: 162px; @codeTopOffsetDesktop: 162px; @codeLeftOffsetMobile: 20px; @codeLeftOffsetTablet: 20px; @codeLeftOffsetDesktop: 25px; @codeMaxWidthMobile: 195px; @codeMaxWidthTablet: 195px; @codeMaxWidthDesktop: 195px;

➡ Das ist typischerweise der wichtigste Bereich, den Kund:innen anpassen müssen, damit:

  • Input exakt über einem “Code-Feld” im Hintergrundbild liegt

  • oder generell richtig platziert ist

So geht’s:

  • @codeTopOffset… → verschiebt nach unten/oben

  • @codeLeftOffset… → verschiebt nach links/rechts

  • @codeMaxWidth… → max. Breite des Code-Containers


3) Buttons und Input (Styling & Anpassungen)

A) Input-Feld anpassen

Das Input-Feld:

input.__up_code_value { ... }

Anpassbar sind u. a.:

  • font-size, line-height

  • padding

  • Textfarbe via @codeFontColor

  • Placeholder-Farbe via @codePlaceholderColor

Beispiel:

@codeFontColor: #555; @codePlaceholderColor: #555;

➡ Wenn der Gutschein-Code auf dem Hintergrund zu schlecht lesbar ist, sollte hier ein höherer Kontrast gewählt werden.


4) Close Button (Position, Farbe, Größe)

Close Button: .__up_close_button

Wichtige Variablen:

@closeButtonSize: 24px; @closeButtonTopOffsetMobile: 12px; @closeButtonRightOffsetMobile: 12px; @closeButtonTopOffsetTablet: 14px; @closeButtonRightOffsetTablet: 14px; @closeButtonTopOffsetDesktop: 14px; @closeButtonRightOffsetDesktop: 14px; @closeButtonColor: #333;

➡ Wenn Kund:innen den Button versetzen möchten:

  • @closeButtonTopOffset…

  • @closeButtonRightOffset…

➡ Wenn er zu klein/groß ist:

  • @closeButtonSize


5) Responsives Verhalten (Mobile / Tablet / Desktop)

Das Pop-up arbeitet mit Breakpoints:

  • Mobile: Standard

  • Tablet: min-width: 440px

  • Desktop: min-width: 756px

Damit können:

  • Pop-up-Größe

  • Background-Image

  • Positionen des Inputs

je nach Gerät getrennt gesteuert werden.

Beispiel:

@media screen and (min-width: 756px) { .__up_pop:before { background-image: @backgroundImageDesktop; } }

✅ Wichtig: Kund:innen sollten Desktop- & Mobile-Hintergrundbild getrennt optimieren, weil sonst Cropping/Lesbarkeit nicht passt.

 

 

 

Bounce Popup MVP

Bildschirmfoto 2026-05-29 um 14.00.32.png
<div class="__up_activation"> <div class="__up_background __up_hidden" id="__up_pop_bg" data-up-close-event="background"></div> <div class="__up_pop __up_hidden"> <svg class="__up_close_icon" data-up-close-event="close-x" id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" > <path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="black" /> </svg> <div class="__up_pop_content"> <h2 class="__up_header_text">Sichere dir jetzt</h2> <h1 class="__up_headline_text"> 5 &euro; Rabatt </h1> <h2 class="__up_underline_text">auf diesen Einkauf.*</h2> <div class="__up_action"> <div class="__up_code_wrapper"> <input id="__up_code_value" readonly type="text" class="__up_code_value" value="{{dynamicVoucherCode}}"/> <label for="__up_code_value" class="__up_code_value_input_label">Gutscheincode</label> <button class="__up_action_button" onclick=" navigator.clipboard.writeText(document.getElementById('__up_code_value').value) .then(() => this.textContent = 'GUTSCHEIN KOPIERT!'); " data-up-event="copy" > GUTSCHEIN KOPIEREN </button> </div> </div> <div class="__up_dismiss" data-up-close-event="dismiss">Nein danke, ich m&ouml;chte keinen Gutschein.</div> <div class="__up_footer">* Nur für Neukunden, 100€ Mindestbestellwert, nicht kombinierbar mit anderen Gutschein- oder Rabattcodes, kann nicht für den Kauf von Büchern oder Geschenkgutscheinen verwendet werden. Eine Eingabe bei Zahlung mit PayPal Express technisch nicht möglich.</div> </div> </div> </div>
@buttonColor: rgba({{buttonColor.r}}, {{buttonColor.g}}, {{buttonColor.b}}, {{buttonColor.a}}); @buttonFontColor: rgba({{buttonFontColor.r}}, {{buttonFontColor.g}}, {{buttonFontColor.b}}, {{buttonFontColor.a}}); @headingColor: rgba({{headingColor.r}}, {{headingColor.g}}, {{headingColor.b}}, {{headingColor.a}}); @inputColor: rgba({{inputColor.r}}, {{inputColor.g}}, {{inputColor.b}}, {{inputColor.a}}); @textColor: rgba({{textColor.r}}, {{textColor.g}}, {{textColor.b}}, {{textColor.a}}); @font-family: '{{font}}', 'Helvetica Neue', Arial; @font-family-bold: '{{fontBold}}', 'Helvetica Neue', Arial; @backgoundColor: rgba({{backgroundColor.r}}, {{backgroundColor.g}}, {{backgroundColor.b}}, {{backgroundColor.a}}); @buttonHoverColor: hsl(from @buttonColor h 76 47); @buttonFocusColor: hsl(from @buttonColor h s 67); #__up_pop_bg { position: fixed; top: 0; left: 0; opacity: 0; } .__up_activation { box-sizing: initial; text-align: left; line-height: 1; .__up_background { pointer-events: none; visibility: hidden; display: block; height: 100%; width: 100%; z-index: 9998; top: 0; left: 0; opacity: 0; backdrop-filter: blur(4px); background-color: rgba(0, 0, 0, 0.4); @keyframes background-open { 0% { opacity: 0; visibility: hidden; pointer-events: none; } 100% { opacity: 1; visibility: visible; pointer-events: auto; } } @keyframes background-close { 0% { opacity: 1; visibility: visible; pointer-events: auto; } 100% { opacity: 0; visibility: hidden; pointer-events: none; } } &.__up_visible { animation-duration: 0.5s; animation-name: background-open; animation-fill-mode: both; animation-delay: 0s; } &.__up_hidden { animation-duration: 0.5s; animation-name: background-close; animation-fill-mode: both; animation-delay: 0s; } } .__up_pop { position: fixed; border-radius: 8px; left: 50%; top: 50%; transform: translateX(-50%); z-index: 999999; background-color: @backgoundColor; background-repeat: no-repeat; box-shadow: 0px 0px 8px 0px #00000040; @keyframes open-pop { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0); } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); } } @keyframes close-pop { 0% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(0); } } &.__up_visible { animation-duration: 0.5s; animation-name: open-pop; animation-fill-mode: both; animation-delay: 0s; } &.__up_hidden { opacity: 0; } &.__up_hide { animation-duration: 0.3s; animation-name: close-pop; animation-fill-mode: both; animation-delay: 0s; } .__up_close_icon { position: absolute; top: 16px; right: 16px; cursor: pointer; width: 24px; height: 24px; background-color: transparent; svg { fill: @textColor; } } .__up_pop_content { padding: 80px 220px; .__up_header_text { font-family: @font-family; color: @textColor; font-size: 25px; line-height: 36px; text-align: center; letter-spacing: normal; word-break: normal; font-weight: 200; margin: 0 0 16px; } .__up_headline_text { font-family: @font-family-bold; color: @headingColor; font-weight: 700; font-size: 100px; line-height: 100px; letter-spacing: normal; word-break: normal; text-align: center; white-space: nowrap; margin: 0 0 16px; } .__up_underline_text { .__up_header_text(); margin: 0 0 80px; } .__up_action { position: relative; border-radius: 8px; margin: 0 5px 24px; .__up_show_button { position: absolute; z-index: 2; cursor: pointer; display: block; padding: 16px 32px; background-color: @buttonColor; background: @buttonColor; color: @buttonFontColor; font-family: @font-family; font-weight: 500; font-size: 25px; line-height: 25px; letter-spacing: normal; word-break: normal; text-align: center; text-transform: uppercase; border: none; border-radius: 8px; transition: background-color 300ms linear; box-shadow: 0px 3px 3px 0px #00000029; height: 82px; box-sizing: border-box; left: 0; right: 0; &:hover { background-color: @buttonHoverColor; } &:focus { background-color: @buttonFocusColor; } &.__up_hidden { display: none; } } .__up_code_wrapper { display: flex; flex-direction: row; justify-content: center; width: auto; gap: 8px; .__up_code_value { border: none; outline: none; box-shadow: none; border-radius: 8px; font-family: @font-family; background-color: @inputColor; color: @textColor; transition: all 300ms linear; font-size: 24px; line-height: 24px; font-weight: 400; letter-spacing: normal; word-break: normal; text-align: center; flex: 1; min-width: 400px; padding: 0 16px; &.__up_code_input_copied { background-color: @buttonColor; color: @buttonFontColor; } } .__up_code_value_input_label{ visibility: hidden; width: 0; } .__up_action_button { cursor: pointer; padding: 16px 32px; background-color: @buttonColor; font-family: @font-family; color: @buttonFontColor; font-weight: 500; font-size: 25px; line-height: 25px; letter-spacing: normal; word-break: normal; text-align: center; text-transform: uppercase; border: none; border-radius: 8px; box-shadow: 0px 3px 3px 0px #00000029; transition: background-color 300ms linear; width: min-content; &:hover { background-color: @buttonHoverColor; } &:focus { background-color: @buttonFocusColor; } } &.__up_visible { opacity: 1; } &.__up_hidden { opacity: 0; } } } .__up_dismiss { cursor: pointer; font-size: 20px; line-height: 20px; font-family: @font-family; letter-spacing: normal; word-break: normal; color: @buttonColor; font-weight: 300; text-align: center; text-decoration: underline; margin: 0 0 16px; } .__up_footer { font-size: 14px; line-height: 14px; font-family: @font-family; color: @textColor; letter-spacing: normal; word-break: normal; font-weight: 400; text-align: center; } } } }
//Custom Condition if(document.referrer.includes("https://www.bundeswehr-und-mehr.de")) { return false; } const KEY = "__up_pop_block_cleanup_executed"; const TTL = 24 * 60 * 60 * 1000; // 24 hours const stored = localStorage.getItem(KEY); if (stored) { const timestamp = Number(stored); if (Date.now() - timestamp < TTL) { return false; } localStorage.removeItem(KEY); } return true;
// User Closes Popup Tracking Code const KEY = "__up_pop_block_cleanup_executed"; localStorage.removeItem("*__up_pop_block"); localStorage.removeItem("3__up_pop_block"); return true;
//Popup is displayed Tracking Code const KEY = "__up_pop_block_cleanup_executed"; localStorage.setItem(KEY, Date.now());
Bildschirmfoto 2026-05-29 um 14.02.45.png