Die wichtigsten Neuerungen in Chrome 135 für moderne Web-Entwicklung
Chrome 135 markiert einen Wendepunkt: Endlich können Entwickler Carousels, Dialoge und Popovers komplett ohne JavaScript erstellen. Die neuen CSS-Pseudo-Elemente ::scroll-button() und ::scroll-marker() sowie die Invoker Commands API machen tausende Zeilen JS-Code überflüssig – und bringen bessere Accessibility gleich mit.
CSS-Carousels: Der Game-Changer
Jahrelang waren Carousels synonym mit JavaScript-Frameworks wie Swiper, Slick oder Glide. Chrome 135 beendet diese Ära mit CSS Overflow 5 Specification-Features.
Die neuen Pseudo-Elemente
::scroll-button()
Browser-native, interaktive Scroll-Buttons, die automatisch 85% eines Scroll-Bereichs navigieren:
.carousel {
overflow-x: scroll;
scroll-snap-type: x mandatory;
}
.carousel::scroll-button(prev) {
content: "←";
background: rgba(0, 0, 0, 0.5);
color: white;
padding: 1rem;
}
.carousel::scroll-button(next) {
content: "→";
background: rgba(0, 0, 0, 0.5);
color: white;
padding: 1rem;
}
Vorteile:
- Stateful: Browser verwaltet Disabled-States (z. B. “Prev” am Anfang)
- Accessible: ARIA-Rollen und Keyboard-Navigation eingebaut
- Performant: Native Implementierung, kein JS-Overhead
::scroll-marker()
Visuelle Marker (Dots/Thumbnails) für Navigation und Progress-Tracking:
.carousel::scroll-marker {
content: "";
width: 10px;
height: 10px;
background: gray;
border-radius: 50%;
}
.carousel::scroll-marker:checked {
background: blue;
}
Browser zeigt automatisch, welcher Marker aktiv ist – ohne State-Management in JS.
Komplettes Carousel-Beispiel
<div class="carousel">
<img src="slide1.jpg" alt="Slide 1">
<img src="slide2.jpg" alt="Slide 2">
<img src="slide3.jpg" alt="Slide 3">
</div>
.carousel {
display: flex;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scroll-padding-inline: 1rem;
}
.carousel img {
scroll-snap-align: center;
width: 100%;
flex-shrink: 0;
}
/* Buttons automatisch generiert */
.carousel::scroll-button(prev) { content: "←"; }
.carousel::scroll-button(next) { content: "→"; }
/* Markers automatisch generiert */
.carousel::scroll-marker { content: ""; }
Null Zeilen JavaScript. Volle Accessibility.
Warum das revolutionär ist
Typische JS-Carousel-Libraries haben 10-50 KB Code, hunderte Konfigurationsoptionen und fragile Accessibility-Implementierungen. Chrome 135 macht das Browser-nativ:
- Carousel Best Practices vom Browser gehandhabt
- Keyboard-Navigation (Pfeiltasten, Tab, Space) eingebaut
- Screen-Reader-Support automatisch korrekt
- Performance durch native Scroll-APIs
Die Accessibility-Teams bei Chrome/Edge haben sichergestellt: Es ist fast unmöglich, ein zugänglicheres Carousel zu bauen als mit diesen Pseudo-Elementen.
Browser-Support
- Chrome 135+ ✅
- Edge 135+ ✅
- Safari/Firefox: In Entwicklung
Für ältere Browser: Progressive Enhancement via @supports:
@supports selector(::scroll-button(prev)) {
/* Native carousel */
.carousel::scroll-button(prev) { content: "←"; }
}
@supports not selector(::scroll-button(prev)) {
/* Fallback: Zeige basic scrollable container */
.carousel { overflow-x: auto; }
}
Invoker Commands: Deklarative UI-Logik
Die Invoker Commands API (command + commandfor) erlaubt es, HTML-Elemente direkt zu steuern – ohne onclick-Handler.
Die Basics
HTML-Attribute:
commandfor: ID des Ziel-Elementscommand: Aktion (toggle-popover,show-modal,close, etc.)
Beispiel: Dialog ohne JavaScript
<!-- Trigger-Button -->
<button commandfor="settings-dialog" command="show-modal">
Einstellungen öffnen
</button>
<!-- Dialog -->
<dialog id="settings-dialog">
<h2>Einstellungen</h2>
<p>Inhalt hier...</p>
<button commandfor="settings-dialog" command="close">
Schließen
</button>
</dialog>
Kein dialog.showModal(), kein dialog.close() – Browser übernimmt alles.
Unterstützte Built-in Commands
Dialogs:
show-modal: Öffnet Dialog als Modal (Backdrop + Trap-Focus)close: Schließt Dialog
Popovers:
toggle-popover: Togglet Popover-Sichtbarkeitshow-popover: Zeigt Popoverhide-popover: Versteckt Popover
Details/Summary:
open: Öffnet<details>-Elementclose: Schließt<details>-Element
Custom Commands
Mit ---Präfix kannst du eigene Commands definieren:
<button commandfor="menu" command="--explode">
Explodieren!
</button>
<div id="menu"></div>
document.getElementById('menu').addEventListener('command', (event) => {
if (event.command === '--explode') {
// Custom-Logik hier
event.target.classList.add('exploding');
}
});
Vorteile:
- Semantische Trennung: HTML beschreibt Struktur, JS nur Custom-Logic
- Accessibility: Browser kennt Intent (z. B. Modal öffnen) und handhabt Keyboard/Screen-Reader
- Wartbarkeit: Keine Event-Listener-Suppe in JS-Files
Browser-Support
Baseline Support erreicht:
- Chrome 135+ ✅
- Edge 135+ ✅
- Opera 120+ ✅
- Safari 26.2+ ✅
- Firefox Nightly (in Entwicklung)
Polyfill verfügbar für ältere Browser: GitHub Polyfill
Weitere Chrome 135 Highlights
CSS shape() Function
Neue Funktion für clip-path und offset-path, um komplexe Pfade zu definieren:
.element {
clip-path: shape(
from 0% 0%,
line to 100% 0%,
arc to 100% 100% of 50%,
line to 0% 100%,
close
);
}
Ersetzt SVG-Pfade in vielen Fällen – einfacher lesbar und wartbar.
MediaStreamTrack in Web Speech API
Websites können jetzt Web Speech API für Remote-Audio nutzen (z. B. Captions für Video-Calls):
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recognition = new webkitSpeechRecognition();
recognition.lang = 'de-DE';
// NEU in Chrome 135: MediaStreamTrack Support
const audioTrack = stream.getAudioTracks()[0];
recognition.audioTrack = audioTrack;
recognition.start();
Use-Cases: Live-Untertitel für Remote-Meetings, Transkription von Podcasts, Voice-Control in WebRTC-Apps.
highlightsFromPoint API
Interaktion mit Custom Highlights (z. B. Text-Marker):
const highlights = CSS.highlights.get('search-results');
document.addEventListener('click', (event) => {
const highlightsAtPoint = CSS.highlightsFromPoint(event.clientX, event.clientY);
if (highlightsAtPoint.includes('search-results')) {
// User klickte auf markierten Text
showContextMenu();
}
});
Ideal für: Annotation-Tools, Kommentar-Systeme, interaktive Tutorials.
Device-Bound Session Credentials
Sichere Session-Bindung an ein Gerät mit automatischer Erneuerung:
// Server fordert Device-Bound Session an
const credential = await navigator.credentials.create({
publicKey: {
challenge: serverChallenge,
rp: { name: "Example Corp" },
user: { id: userId, name: userName },
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { authenticatorAttachment: "platform" }
}
});
// Browser erneuert Session automatisch mit Proof-of-Possession
Security-Vorteil: Session-Hijacking wird extrem schwer – selbst bei Token-Diebstahl kann Angreifer ohne Device nicht zugreifen.
setInterval(0) ohne Clamping
Vor Chrome 135: setInterval(..., 0) wurde auf 1ms geclampt.
Ab Chrome 135: 0ms ist wirklich 0ms – wichtig für High-Frequency-Updates (z. B. Game-Loops, Audio-Processing).
// Jetzt wirklich 0ms statt 1ms
setInterval(() => {
updateGameState();
}, 0);
Chrome Extensions: userScripts.execute()
Neue Methode für einmalige User-Script-Injektion statt permanenter Registrierung:
chrome.userScripts.execute({
target: { tabId: tab.id },
func: () => {
// Einmalige Custom-Logic
document.body.style.filter = 'invert(1)';
}
});
Vorteil: Temporäre Scripts ohne Pollution der permanenten Registry.
DevTools-Verbesserungen
Performance Panel:
- Redesigned UI mit klareren Metrics
- Bessere Visualisierung von Long Tasks
Accessibility Tree View:
- Neuer Tab in Elements-Panel
- Zeigt ARIA-Tree wie Screen-Reader ihn sieht
Empty States:
- Alle Panels haben jetzt hilfreiche Leer-Zustände mit Tipps
Migration-Tipps
Von JS-Carousels zu CSS
Vorher (Swiper):
new Swiper('.carousel', {
navigation: { nextEl: '.next', prevEl: '.prev' },
pagination: { el: '.pagination', clickable: true },
scrollbar: { el: '.scrollbar' },
});
Nachher (CSS):
.carousel {
overflow-x: scroll;
scroll-snap-type: x mandatory;
}
.carousel::scroll-button(prev) { content: "←"; }
.carousel::scroll-button(next) { content: "→"; }
.carousel::scroll-marker { content: ""; }
Gewinn: ~40 KB weniger Bundle, bessere Accessibility, kein JS-Fehler-Risiko.
Von onclick zu Invoker Commands
Vorher:
<button onclick="document.getElementById('modal').showModal()">
Open
</button>
Nachher:
<button commandfor="modal" command="show-modal">
Open
</button>
Gewinn: Deklarativ, besser verständlich, Browser optimiert Accessibility.
Fazit: Weniger Code, mehr Browser
Chrome 135 setzt die Trend fort: Platform über Polyfills. Features, die jahrelang JS-Libraries brauchten, werden Browser-nativ – mit besserer Performance und Accessibility.
Was sich ändert:
- Carousels:
::scroll-button()+::scroll-marker()→ keine Swiper/Slick mehr nötig - Dialogs/Popovers: Invoker Commands → keine
onclick-Handler mehr - Custom Paths:
shape()→ CSS statt SVG-Pfade - Speech-to-Text: MediaStreamTrack-Support → Remote-Audio-Captions
- Security: Device-Bound Sessions → robustere Auth
Nächste Schritte:
- Experimentieren: Chrome 135+ installieren, neue Features testen
- Progressive Enhancement: CSS-Carousels mit Fallback für ältere Browser
- Polyfills nutzen: Invoker Commands Polyfill für breitere Kompatibilität
- Lighthouse checken: Neue Metrics für CSS Carousels + Invoker Commands
Die Zukunft ist deklarativ. Chrome 135 beweist: Die besten Features brauchen kein JavaScript.
Sources:
- New in Chrome 135 | Chrome for Developers
- Chrome 135 Release Notes
- What’s new in DevTools, Chrome 135
- Chrome 135 beta
- CSS Wrapped 2025
- Introducing command and commandfor
- Carousels with CSS
- Chrome 135 Brings ::scroll-button() and ::scroll-marker()
- HTML Invoker Commands Achieve Baseline Support
- command and commandfor: the Invoker Commands API