Kleines Kino für lau – wie ein Bild auf einer Webseite lebendig wird
Ein Beitragsbild muss nicht einfach nur angezeigt werden. In diesem Laborprotokoll zeige ich, wie aus einer langweiligen Standard-Bildanzeige eine kleine Inszenierung wird: Das Bild löst sich aus seinem Container, fliegt in die Bildschirmmitte, entfaltet sich und kehrt beim Schließen exakt zurück.
Ein Beitragsbild ist auf den meisten Webseiten nichts weiter als Dekoration. Es steht oben, füllt Platz, sieht vielleicht gut aus – und wird übersehen. Scroll. Weg. Vergessen. Das ist kein Problem der Technik. Meistens hat der Entwickler keine Lust, mehr draus zu machen.
Denn zwischen „Bild anzeigen" und „Moment erzeugen" liegen keine Wochen Entwicklung. Es liegt nur die Entscheidung, ob man dem Besucher etwas zutraut – oder ihm einfach nur Standard präsentiert.
Vom Bild zur Szene
In diesem praktischen Beispiel, das ich bei den Laborprotokollen und bei meinen Songs umgesetzt habe, passiert etwas anderes: Das Hauptbild bekommt einen Zauber. Ein Klick schafft den "Oh-Effekt". Das Bild löst sich von seiner Position, es tritt aus seiner Umgebung heraus. Es bekommt Raum. Und der Besucher staunt - hoffentlich.
What? Um was geht's?
Beim Klick passiert kein banales „größer werden". Es passiert eine Bewegung, die sich wie eine kleine Reise anfühlt:
- Das Bild verlässt seinen Container
- Es übernimmt exakt seine Ausgangsposition
- Es fliegt in die Mitte des Bildschirms
- Dreht sich, skaliert, entfaltet sich
- Und kommt beim Schließen exakt dorthin zurück, wo es herkam
Das ist kein Effekt. Das ist ein guter Move, um zu zeigen: Hier passiert etwas. Hier hat jemand mitgedacht.
Beispiele: Fui zlang her (Remastered 2026) oder hier Für jeden Job das richtige Werkzeug – und der Mut, Nein zu sagen oder einfach hier bei diesem Artikel bei dem Beitragsbild austesten.
Der Trick: Ein Doppelgänger mit sauberem Startpunkt
Das Originalbild selbst bleibt an seinem Platz. Es wird nicht durch die Gegend geschoben, nicht aus dem Layout gerissen und nicht mit Gewalt vergrößert. Genau das wäre der typische Fehler. Stattdessen erzeugt JavaScript einen visuellen Doppelgänger – ein sogenanntes Ghost-Element.
Dieser Doppelgänger übernimmt exakt die aktuelle Position, Breite, Höhe und Form des Originals. Dadurch entsteht für den Besucher der Eindruck, als würde wirklich das angeklickte Bild aus der Seite herausfliegen.
function makeGhost(originalImg) {
const rect = originalImg.getBoundingClientRect();
const ghost = document.createElement('img');
ghost.src = originalImg.currentSrc || originalImg.src;
ghost.alt = originalImg.alt || '';
ghost.className = 'rw-portal-ghost';
ghost.style.left = rect.left + 'px';
ghost.style.top = rect.top + 'px';
ghost.style.width = rect.width + 'px';
ghost.style.height = rect.height + 'px';
document.body.appendChild(ghost);
return {
ghost: ghost,
rect: rect
};
}
.rw-portal-ghost {
position: fixed;
z-index: 100000;
object-fit: cover;
border-radius: 28px;
pointer-events: none;
transform-origin: center center;
box-shadow:
0 28px 80px rgba(0,0,0,.45),
0 0 0 1px rgba(255,255,255,.18);
}
Der wichtige Punkt ist getBoundingClientRect(). Damit wird nicht geraten, wo das Bild steht. Es wird gemessen. Pixelgenau. Genau deshalb wirkt die Animation nicht wie ein Overlay von außen, sondern wie ein echtes Herauslösen aus der Seite.
Das Ziel: Mitte des Bildschirms, aber proportional
Das Ghost-Bild soll nicht einfach stumpf auf 90 Prozent Bildschirmbreite gesetzt werden. Es soll groß wirken, aber seine Proportionen behalten und nicht über den Rand hinauslaufen. Also wird die Zielgröße berechnet.
function getTargetBox(rect) {
const maxWidth = window.innerWidth * 0.86;
const maxHeight = window.innerHeight * 0.78;
const scale = Math.min(
maxWidth / rect.width,
maxHeight / rect.height
);
const targetLeft = (window.innerWidth - rect.width * scale) / 2;
const targetTop = (window.innerHeight - rect.height * scale) / 2;
return {
scale: scale,
left: targetLeft,
top: targetTop
};
}
Das ist der Teil, der verhindert, dass die Animation auf verschiedenen Bildschirmgrößen auseinanderfällt. Desktop, Tablet, Handy – das Bild sucht sich seinen Platz, statt blind irgendwohin zu knallen.
Der eigentliche Start: zwei Frames warten
Jetzt kommt der kleine technische Zauber. Das Ghost-Element wird zuerst in seiner Startposition ins DOM gesetzt. Danach darf der Browser einmal Luft holen. Und dann noch einmal. Erst dann wird die Zielposition gesetzt.
function openImagePortal(originalImg) {
const data = makeGhost(originalImg);
const ghost = data.ghost;
const rect = data.rect;
const target = getTargetBox(rect);
originalImg.classList.add('rw-original-hidden');
document.body.classList.add('rw-portal-is-open');
requestAnimationFrame(function() {
requestAnimationFrame(function() {
ghost.style.transition = [
'left .95s cubic-bezier(.13,1.08,.28,1)',
'top .95s cubic-bezier(.13,1.08,.28,1)',
'transform .95s cubic-bezier(.13,1.08,.28,1)',
'border-radius .95s ease',
'box-shadow .95s ease'
].join(', ');
ghost.style.left = target.left + 'px';
ghost.style.top = target.top + 'px';
ghost.style.transform = 'scale(' + target.scale + ') rotate(1080deg)';
ghost.style.borderRadius = '34px';
});
});
}
Warum zwei requestAnimationFrame()? Weil der Browser sonst Start- und Zielzustand zu einem einzigen Render-Moment zusammenzieht. Dann gibt es keine Reise, sondern nur einen Sprung. Zwei Frames geben dem Browser genug Zeit, den Anfangszustand wirklich zu registrieren.
.rw-original-hidden {
opacity: .08;
filter: blur(2px) saturate(.7);
transition:
opacity .25s ease,
filter .25s ease;
}
.rw-portal-is-open {
overflow: hidden;
}
Das Overlay kommt nicht sofort. Es tritt nach.
Ein häufiger Fehler bei solchen Effekten: Das dunkle Overlay ist sofort da und erschlägt die Bewegung. Besser ist: Erst bewegt sich das Bild. Dann kommt die Bühne dazu.
function createPortalOverlay() {
const overlay = document.createElement('div');
overlay.className = 'rw-portal-overlay';
overlay.innerHTML = `
<button class="rw-portal-close" type="button" aria-label="Bild schließen">
×
</button>
`;
document.body.appendChild(overlay);
requestAnimationFrame(function() {
overlay.classList.add('is-visible');
});
return overlay;
}
.rw-portal-overlay {
position: fixed;
inset: 0;
z-index: 99990;
opacity: 0;
background:
radial-gradient(circle at 50% 42%,
rgba(80,130,255,.22),
rgba(4,8,22,.92) 58%,
rgba(1,3,10,.98) 100%);
backdrop-filter: blur(18px);
transition: opacity .45s ease;
}
.rw-portal-overlay.is-visible {
opacity: 1;
}
Damit wird aus der Vergrößerung eine Szene. Das Bild bekommt nicht nur Größe, sondern Atmosphäre.
Schließen: Nicht ausblenden, sondern zurückfliegen
Der Rückweg ist genauso wichtig wie der Hinweg. Wenn das Bild beim Schließen einfach verschwindet, ist der Zauber kaputt. Also wird erneut die Originalposition gemessen – und das Ghost-Element fliegt zurück. Dabei wird die Rückbewegung über transform: scale() und Position gesteuert, nicht über animierte width/height – das ist GPU-freundlicher und läuft flüssiger.
function closeImagePortal(originalImg, ghost, overlay) {
const rect = originalImg.getBoundingClientRect();
overlay.classList.remove('is-visible');
ghost.style.transition = [
'left .72s cubic-bezier(.18,.9,.22,1)',
'top .72s cubic-bezier(.18,.9,.22,1)',
'transform .72s cubic-bezier(.18,.9,.22,1)',
'border-radius .72s ease'
].join(', ');
ghost.style.left = rect.left + 'px';
ghost.style.top = rect.top + 'px';
ghost.style.transform = 'scale(1) rotate(0deg)';
ghost.style.borderRadius = '28px';
window.setTimeout(function() {
originalImg.classList.remove('rw-original-hidden');
document.body.classList.remove('rw-portal-is-open');
if (ghost && ghost.parentNode) {
ghost.parentNode.removeChild(ghost);
}
if (overlay && overlay.parentNode) {
overlay.parentNode.removeChild(overlay);
}
}, 760);
}
Das Schöne daran: Der Besucher versteht unbewusst, woher das Bild kam und wohin es zurückgeht. Das UI verliert ihn nicht. Es nimmt ihn mit.
Die kleine Einladung vor dem großen Effekt
Damit der Besucher überhaupt merkt, dass das Bild mehr kann, braucht es ein Signal. Kein fetter Button. Keine laute Aufforderung. Nur eine kleine Hover-Pill, die sich elegant ins Bild schiebt.
.rw-cover-pan {
position: relative;
overflow: hidden;
border-radius: 30px;
}
.rw-portal-btn {
position: absolute;
right: 16px;
bottom: 16px;
z-index: 5;
display: inline-flex;
align-items: center;
gap: 10px;
padding: 9px 15px;
border-radius: 999px;
color: #fff;
font-weight: 800;
font-size: 14px;
background: rgba(8,14,32,.74);
border: 1px solid rgba(255,255,255,.18);
backdrop-filter: blur(14px);
opacity: 0;
transform: translateY(8px) scale(.72);
transition:
opacity .25s ease,
transform .32s cubic-bezier(.34,1.56,.64,1),
background .25s ease,
border-color .25s ease;
}
.rw-cover-pan:hover .rw-portal-btn {
opacity: 1;
transform: translateY(0) scale(1);
}
.rw-portal-btn:hover {
background: rgba(34,78,180,.82);
border-color: rgba(255,255,255,.32);
}
Diese kleine Pill ist fast unscheinbar. Aber sie verändert alles. Sie sagt: Dieses Bild ist nicht nur Deko. Dieses Bild ist klickbar. Hier wartet etwas.
Warum die Bewegungskurve kein Zufall ist
Diese Kurve hier steht an zwei entscheidenden Stellen:
cubic-bezier(.13, 1.08, .28, 1) /* Hinflug: überzieht leicht, setzt sich dann */
cubic-bezier(.34, 1.56, .64, 1) /* Hover-Pill: federt ein */
Beide sorgen dafür, dass Bewegung nicht mechanisch wirkt. Nicht linear. Nicht tot. Sondern mit einem Hauch von Physik – als hätte das Element ein kleines bisschen Gewicht.
Das ist der Unterschied zwischen „läuft" und „fühlt sich gut an".
Barrierearm gedacht: Escape und Klick außerhalb
Auch ein kleiner Kinoeffekt darf nicht zur Falle werden. Deshalb muss das Portal sauber geschlossen werden können: über den Close-Button, über Escape und über einen Klick auf das Overlay.
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeCurrentPortal();
}
});
document.addEventListener('click', function(event) {
if (event.target.classList.contains('rw-portal-overlay')) {
closeCurrentPortal();
}
});
Das ist der Unterschied zwischen Effekt und Benutzerführung. Der Besucher darf staunen, aber er muss jederzeit wieder rauskommen.
Die komplette Grundidee in einem Satz
Original messen.
Ghost erzeugen.
Browser rendern lassen.
Ghost ins Zentrum schicken.
Overlay nachziehen.
Beim Schließen alles rückwärts.
Mehr ist es technisch gar nicht. Aber genau darin liegt der Reiz: Aus einer normalen Bildanzeige wird kein schweres Plugin, keine Galerie, kein aufgeblasenes System. Es wird eine kleine, kontrollierte Inszenierung.
Warum das funktioniert
Weil es den Besucher ernst nimmt.
Eine Aktion wird nicht nur ausgeführt – sie wird inszeniert.
Ein Klick bekommt eine Reaktion, die größer ist als nötig.
Und genau deshalb bleibt sie hängen.
Das eigentliche Experiment
Der Aufwand für das Ganze liegt irgendwo zwischen „ein paar Zeilen CSS" und „ein sauberer JavaScript-Block".
Der Effekt liegt weit darüber.
Das ist die eigentliche Erkenntnis:
Nicht weniger ist mehr.
Mehr Gefühl ist mehr.
Und manchmal reicht dafür ein einziges Bild – das sich weigert, einfach nur still dazustehen.