material 3 auf einer persönlichen seite: was überlebte, was nicht

dev · Oct 4, 2026 · 5 min read

diese seite läuft auf material 3. nicht davon inspiriert, nicht lose darauf aufgebaut — die echten token-namen, die echten palettenschemata, die echte formsprache. ich wollte wissen, ob ein für eine handy-app gebautes designsystem den kontakt mit einer persönlichen seite übersteht, die völlig andere prioritäten hat.

kurze antwort: rund 70% davon haben überlebt, und die 30%, die gestorben sind, sind der teil, den ich am liebsten fallengelassen habe.

was reinkam

die token-ebene, die das eigentliche ist. --primary-container, --on-primary-container, --surface-variant, --outline-variant — das sind die m3-namen, nicht meine eigenen, und jede komponente konsumiert sie, statt eine farbe fest zu verdrahten. das ist der teil, der sich am meisten ausgezahlt hat, und nicht aus ästhetischen gründen.

er hat sich ausgezahlt, weil ich beim Schreiben die ganze seite sechsmal von hell auf dunkel und zurück sowie die akzentfarbe umgestellt habe. nichts ist kaputtgegangen. es gibt kein if (dark) in meinen komponenten. jede farbe im stylesheet löst sich über eine variable auf, und die dunkle palette ist ein zweiter werte-satz für dieselben namen.

alle sechs palettenschemata: tonal-spot, fidelity, content, neutral, expressive und fruit-salad. sie sind im einstellungs-dialog und sie funktionieren alle, weil sie das sind, was m3 so nennt, und nicht sechs handgetunte themes.

die formskala. m3 hat eine definierte eckenradius-leiter, und karten sitzen an deren spitze. meine karten sind rounded-[2.4rem], knöpfe gehen vollständig rund, navigations-pills ebenfalls. das ist das einzige m3-merkmal, das am leichtesten wiederzuerkennen ist, und es übersteht die übersetzung in eine persönliche seite mühelos.

der ripple, in der richtigen deckkraft:

opacity: var(--ripple-hover-opacity, 0.08);

0.08 ist der m3-wert der state layer. es fühlt sich fast zu subtil an, und das ist richtig — der sinn des state layer ist, dass man ihn nicht bewusst wahrnehmen soll.

der ripple-umfang. das war der teil, von dem ich nicht wusste, dass ich ihn brauche. der ripple folgt dem zeiger nur innerhalb des elements, das du wirklich gedrückt hast, nicht der ganzen seite. es lässt schnelle klicks präzise wirken statt schlampig.

die komponenten, die als kleine webversionen sinn machten: schalter, regler, textfeld und zwei scrollleisten, eine für das fenster und eine für panels. das sind reine gewinne.

was ich weggeworfen habe

elevation. m3 definiert sechs stufen, 0 bis 5, mit einem bestimmten schatten für jede. ich benutze keine davon. in meinem stylesheet steht kein einziges elevation-token, und die einzigen schatten darin sind hover-zustände auf karten und knöpfen — nichts, das beschreibt, wie hoch eine fläche sitzt.

das war keine faulheit, es war eine entscheidung. das m3-elevationsmodell nimmt undurchsichtige flächen an, die aufeinander stapeln. diese seite hat eine durchscheinende seitenleiste mit backdrop-blur, und inhalt, der darunter durchscrollt. elevation ist eine tiefenmetapher für undurchsichtige ebenen; wenn die ebene durchsichtig ist, lügt der schatten darüber, was worauf liegt. hier trennen also grenzen, nicht schatten.

die m3-elevationswerte sind gut, und ich habe den geist übernommen — grenzen bei --outline-variant, radius an der spitze der skala — ohne die tokens zu kopieren.

die typografie-skala. m3 hat fünf rollen: display, headline, title, body, label, jede mit drei größen. ich benutze ungefähr zwei davon, denn eine display-rolle, die für ein handy bemessen ist, bringt dich auf etwa 57px, und das ist auf einem breiten bildschirm keine überschrift. die skala übersteht den sprung von einem 6-zoll-viewport auf 2560px nicht ohne neu skalierung, und sobald du neu skaliert hast, benutzt du nicht mehr die m3-skala, sondern deine eigene, die ihr ähnelt.

ich habe die idee behalten — eine einzige expressive display-schrift für die großen momente, eine monospace für die entwickler-oberflächen, schlichte sans für den fließtext — und die konkrete rampe weggeworfen.

das eine, das nie funktioniert hat

bewegung.

m3 gibt dauer und easing-kurven vor, und die sind für ein handy abgestimmt: kurz, weil ein daumen nah am bildschirm ist. auf einer desktop-seite mit zeiger fühlen sich dieselben kurven träge an, auf eine art, die sich schwer in worte fassen lässt. mein auge ist nicht da, wo mein daumen wäre.

das größere problem: spezifikationen, die voller bewegung sind, nehmen ein verlässliches frame-budget an. sie nehmen nicht an, dass das frame-budget null sein könnte.

da bin ich hart gestoßen. meine sidebar-einklapp-animation hörte stillschweigend auf zu funktionieren: die box blieb für immer auf voller breite, ohne fehler irgendwo. die ursache war nicht die animationslogik, sondern eine layout-projektion, die gegen eine breiten-transition auf demselben element kämpfte — zwei dinge, die beide die box beanspruchten, und der verlierer erreichte nie seinen endwert. und der einzige grund, warum ich es gefunden habe, war, dass ich die berechnete breite gemessen habe, statt darauf zu vertrauen, dass der code „richtig aussah".

ich habe die breite aus einem motion-wert in eine normale css-transition verschoben und die layout-projektion gelöscht. die box erreicht ihr ziel jetzt in 60ms, gemessen, jedes mal.

die lehre ging nicht um framer motion. sie war, dass ein designsystem dir sagt, wie ein fertiger zustand aussieht, und nichts darüber sagt, wie man dort hinkommt, wenn das frame-budget einbricht. für eine handy-app hält diese annahme. für eine webseite in einem browser-tab, den jemand in den hintergrund gelegt haben könnte, nicht.

was ich behalten würde, wenn ich nochmal anfinge

die token-ebene, ohne zu zögern. es ist der teil von m3, der außerhalb von android wirklich wiederverwendbar ist, und der grund ist langweilig: es ist ein benennungsschema, das dich zwingt, „was ist die rolle dieser farbe" zu beantworten, statt „welche farbe ist das". diese frage lohnt sich, selbst wenn du die material-dokumentation nie öffnest.

die palettenschemata und die formskala, weil sie gratis sind, sobald die tokens existieren.

die deckkraft des state layer, weil es eine einzige zahl ist und sie stimmt.

und elevation, die typrampe und die bewegungskurven: weg, ohne bedauern — sie sind sämtlich annahmen über einen kontext, in dem diese seite nicht ist.

die ehrliche zusammenfassung: m3 ist eine sehr gute antwort auf „wie sieht und fühlt sich eine native android-app an", und ein brauchbarer ausgangspunkt für ein web-designsystem, vorausgesetzt, man behandelt es als vokabular und nicht als spezifikation. die tokens übertragen sich. die pixelwerte nicht.