material 3 in un sito personale: cosa è sopravvissuto, cosa no
dev · Oct 4, 2026 · 5 min read
questo sito gira su material 3. non ispirato a esso, non vagamente basato su di esso — i nomi dei token veri, gli schemi di palette veri, il linguaggio delle forme vero. volevo sapere se un design system costruito per un'app per telefono regge il contatto con un sito personale, che ha priorità completamente diverse.
risposta breve: circa il 70% è sopravvissuto, e il 30% che è morto è la parte di cui sono più contento di essermi liberato.
cosa è entrato
il livello di token, che è la cosa vera. --primary-container, --on-primary-container, --surface-variant, --outline-variant — sono i nomi di m3, non miei nomi, e ogni componente li consuma invece di codificare un colore a mano. è la parte che ha reso di più, e non per ragioni estetiche.
ha reso perché ho passato il sito intero da chiaro a scuro e viceversa, e ho cambiato l'accento, sei volte, mentre lo scrivevo. niente si è rotto. non c'è un if (dark) nei miei componenti. ogni colore nel foglio di stile si risolve attraverso una variabile, e la palette scura è un secondo insieme di valori per gli stessi nomi.
tutti e sei gli schemi di palette: tonal-spot, fidelity, content, neutral, expressive e fruit-salad. sono nel dialog delle impostazioni e funzionano tutti, perché sono quelli che chiama m3 e non sei temi tarati a mano.
la scala delle forme. m3 ha una scala di raggio degli angoli definita e le card stanno in cima. le mie card sono rounded-[2.4rem], i pulsanti sono completamente arrotondati, le pill della nav sono completamente arrotondate. è il segno di m3 più riconoscibile e sopravvive alla traduzione in un sito personale senza problemi.
il ripple, all'opacità corretta:
opacity: var(--ripple-hover-opacity, 0.08);
0,08 è il valore dello state layer di m3. sembra quasi troppo sottile, ed è corretto — il punto dello state layer è che non devi accorgertene consapevolmente.
il ripple scope. è stata la parte che non sapevo di aver bisogno. il ripple segue il puntatore solo dentro l'elemento che hai premuto davvero, non tutta la pagina. fa sentire i clic veloci precisi invece che disordinati.
i componenti che avevano senso come piccole versioni web: switch, slider, campo di testo, e due barre di scorrimento, una per la finestra e una per i pannelli. sono vittorie pure.
cosa ho buttato
l'elevazione. m3 definisce sei livelli, da 0 a 5, con un'ombra specifica per ciascuno. ne uso nessuno. nel mio foglio di stile non c'è un solo token di elevazione, e le uniche ombre sono stati di hover su card e pulsanti — niente che descriva quanto in alto sta una superficie.
non è pigrizia, è una decisione. il modello di elevazione di m3 assume superfici opache impilate l'una sull'altra. questo sito ha una barra laterale translucida con blur sullo sfondo e contenuto che le scorre sotto. l'elevazione è una metafora di profondità per piani opachi; quando il piano è trasparente, l'ombra mente su cosa sta sopra cosa. quindi qui a separare sono i bordi, non le ombre.
i valori di elevazione di m3 sono buoni e ne ho copiato lo spirito — bordi a --outline-variant, raggio in cima alla scala — senza copiare i token.
la scala tipografica. m3 ha cinque ruoli: display, headline, title, body, label, ognuno con tre dimensioni. ne uso circa due, perché un ruolo display dimensionato per un telefono ti dà circa 57px, che non è un headline su uno schermo largo. la scala non sopravvive al salto da una viewport da 6 pollici a una da 2560px senza essere riscalata, e una volta riscalata non stai più usando la scala di m3, stai usando la tua che le assomiglia.
ho tenuto l'idea — un unico carattere espressivo per i momenti grandi, un monospace per le superfici da sviluppatore, un sans semplice per il testo — e ho buttato la rampa specifica.
quello che non ha mai funzionato
il movimento.
m3 specifica durate e curve di easing, tarate per un telefono: brevi, perché un pollice è vicino allo schermo. su un sito desktop guidato dal puntatore quelle stesse curve risultano lente in un modo difficile da mettere a parole. il mio occhio non è dove sarebbe il mio pollice.
il problema più grande è che le specifiche pesanti di animazione assumono un budget di frame affidabile. non assumono che il budget di frame possa essere zero.
l'ho colpito duramente. la mia animazione di collasso della barra laterale ha smesso di funzionare in silenzio: la scatola restava a larghezza piena, per sempre, senza errori da nessuna parte. la causa non era la logica dell'animazione ma una proiezione di layout che lottava con una transizione di larghezza sullo stesso elemento — due cose che cercavano di possedere la scatola, e chi perdeva non raggiungeva mai il suo valore finale. e l'unico motivo per cui l'ho trovato è aver misurato la larghezza calcolata invece di fidarmi del fatto che il codice «sembrava giusto».
ho spostato la larghezza da un valore motion a una normale transizione css, e ho cancellato la proiezione di layout. la scatola ora raggiunge il suo obiettivo entro 60ms, misurato, ogni volta.
la lezione non riguardava framer motion. era che un design system ti dice com'è fatto uno stato finale e non dice nulla di come arrivarci quando il budget di frame collassa. per un'app per telefono quell'ipotesi regge. per una pagina web in una scheda che qualcuno potrebbe aver messo in background, no.
cosa terrei se ricominciassi
il livello di token, senza esitazione. è la parte di m3 genuinamente riutilizzabile fuori da android, e il motivo è noioso: è uno schema di nomi che ti obbliga a rispondere «qual è il ruolo di questo colore» invece di «che colore è». quella domanda vale la pena anche se non apri mai la documentazione di material.
gli schemi di palette e la scala delle forme, perché sono gratis una volta che i token esistono.
l'opacità dello state layer, perché è un numero solo ed è giusto.
e l'elevazione, la rampa tipografica e le curve di movimento, via, senza rimpianti — sono tutte ipotesi su un contesto in cui questo sito non si trova.
il riassunto onesto: m3 è una risposta molto buona a «come appare e si sente un'app android nativa», e un discreto punto di partenza per un design system web, purché tu sia disposto a trattarlo come un vocabolario piuttosto che come una specifica. i token si trasferiscono. i valori in pixel no.