Blog

Scroll-Animationen: animation-timeline statt IntersectionObserver

Es gibt einen Grund, warum JavaScript-Parallax immer leicht falsch aussieht – ein bisschen losgelöst, als würden die Ebenen einen halben Frame hinter der Seite schwimmen. Es ist kein nachlässiger Code. Es liegt daran, dass Scroll-Ereignisse JavaScript erst erreichen, nachdem der Browser das Scrollen bereits gerendert hat. Der Browser hat das schon einmal gelöst, als er klebende Header in position: sticky verwandelte. Scroll-driven Animations sind derselbe Schritt, auf alle scroll-gebundenen Effekte gleichzeitig angewendet.

View Transitions in Next.js: Seitenanimationen ohne Animationsbibliothek

Zehn Jahre lang bedeutete das Animieren einer Miniatur zu einem Hero-Bild eine einzige Technik: vor dem Element messen, danach messen, den Unterschied mit einem Transform vortäuschen und abspielen. FLIP. Jede Animationsbibliothek macht das so – und jede zahlt dafür mit JavaScript auf dem Hauptthread im denkbar schlechtesten Moment. Die View Transitions API verlagert diesen Trick in den Browser – und seit React 19.2 und Next.js 16 besteht der gesamte Vertrag aus einem einzigen Prop namens name.

content-visibility: Offscreen-Rendering ohne Listen-Virtualisierung

Eine Liste mit tausend Kommentaren rendert langsam, also greifst du zu react-window – und tauschst dafür flüssiges Scrollen gegen Strg+F, den Seitendruck und teilweise die Navigation von Screenreadern ein, weil Elemente außerhalb des sichtbaren Bereichs physisch aufhören, im DOM zu existieren. content-visibility löst dasselbe Problem anders: Die Elemente bleiben im DOM, der Browser überspringt für sie nur die teure Layout- und Malarbeit, solange sie nicht in der Nähe des sichtbaren Bereichs sind – und kann sie, überraschenderweise, vorübergehend wieder sichtbar machen, wenn du in ihnen nach Text suchst.

Popover API und natives <dialog>: Schluss mit von Hand gebauten Modals

Im Artikel über Barrierefreiheit war ein Modal mit display:none, das trotzdem noch im Accessibility-Baum existierte, ein Beispiel für einen Fehler, der beim Bau eines Modals von Grund auf mit Divs entsteht. Die eigentliche Frage lautet: Warum musste man es überhaupt von Grund auf bauen? Ich schaue mir an, was das native <dialog> und das popover-Attribut kostenlos mitbringen – Top Layer, Fokusfalle, Light Dismiss – und wo sich diese beiden Mechanismen so sehr unterscheiden, dass eine Verwechslung schnell zu einer unzugänglichen Oberfläche führt.

CSS @layer: wie Cascade Layers den Krieg um die Spezifität beenden

Die Utility-Klasse .mt-4 verliert gegen die Regel .card .card__header .card__title, obwohl sie logisch gewinnen sollte, weil sie später hinzugefügt wurde. Das ist kein Zufall – das ist Spezifität, die exakt das tut, wofür sie entworfen wurde. @layer führt eine völlig neue Achse zur Konfliktlösung ein, die vor der Spezifität greift, nicht neben ihr – und hat eine Falle, die so unintuitiv ist, dass selbst ein Teil der Dokumentation im Netz sie falsch darstellt.

CSS :has() — der Elternteil, der weiß, was im Inneren passiert

Ein Formularfeld soll sich rot einfärben, wenn der Input darin ungültig ist. Klingt simpel – nur konnte CSS 25 Jahre lang ein Element nicht danach fragen, was in seinem Inneren passiert, sondern immer nur umgekehrt. Ich schaue mir an, wie :has() diese Richtung umkehrt, wie es sich von gewöhnlichen Kombinatoren unterscheidet und wo diese neue Macht die Performance wirklich kostet.