Rosso
La scheda prende il bordo dal radio scelto.
02 Impalcatura
Foglio di stile · sei dimostrazioni
C'era un tempo in cui il CSS impaginava e il JavaScript decideva. Oggi il foglio di stile guarda dentro i propri figli, misura il contenitore in cui vive, si aggancia allo scorrimento e mescola i colori. Questa pagina è un documento di carta che si dimostra da sola: quasi tutto quello che vedi qui funziona con JavaScript disattivato.
Selettore relazionale
:has() — il genitore reagiscePer vent'anni il CSS ha saputo scendere: dal contenitore al figlio. :has()
inverte la freccia. Un elemento può ora vestirsi in base a ciò che contiene:
un modulo che si accende quando un campo ha il fuoco, un pulsante che si abilita solo
con la casella spuntata, una scheda che cambia colore perché dentro è stata scelta
un'opzione.
La regola qui sotto non tocca l'input: tocca il campo che lo contiene. Un solo selettore, nessun listener, nessuna classe aggiunta a mano.
La scheda prende il bordo dal radio scelto.
Nessuna classe sul contenitore.
Solo :has() e variabili.
.campo:has(input:invalid:not(:placeholder-shown)) {
border-color: #d8482a;
}
.modulo:not(:has(.consenso input:checked)) .modulo-invia {
opacity: .35; pointer-events: none;
}
Container query
Una media query chiede al browser quanto è largo il viewport. Una container query chiede quanto è largo il contenitore in cui il componente vive: lo stesso blocco può stare in una colonna laterale da 260 px o a tutta pagina e impaginarsi da solo, senza sapere nulla del dispositivo.
Qui sotto il riquadro è ridimensionabile: afferra il bordo destro o l'angolo e trascinalo. La scritta in alto e le colonne delle schede cambiano a 420 e a 620 px di contenitore — non a 420 px di finestra.
contenitore stretto · una colonna contenitore medio · due colonne contenitore largo · tre colonne
Si impila quando lo spazio è poco.
Entra in coppia oltre i 420 px.
Chiude la fila oltre i 620 px.
↔ trascina il bordo del riquadro
.cq { container-type: inline-size; }
@container (min-width: 420px) {
.cq-griglia { grid-template-columns: 1fr 1fr; }
}
Griglia annidata
Allineare i piedi di tre schede è sempre stato un lavoro da JavaScript o da altezze
minime indovinate. subgrid fa ereditare a una scheda le righe della griglia
che la contiene: titolo, descrizione e piede finiscono sulla stessa linea in tutte e tre
le colonne, anche se i testi sono lunghi in modo diverso.
Spegni la casella e guarda le righe separarsi: è la stessa griglia, senza
subgrid.
Guarda il comportamento reale del browser prima di ipotizzare una regola.
10 minfacile
Togli il codice che non serve, poi togli anche quello che sembrava servire.
25 minmedio
Rifai la stessa cosa da capo senza guardare: è l'unica prova che conta.
5 mindifficile
.sg-griglia { display: grid; grid-template-rows: auto auto auto; }
.sg-scheda { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
Trasformazioni 3D
perspective e transform-style: preserve-3d danno al CSS un
vero spazio a tre assi. Le schede qui sotto non sono immagini: sono elementi con due
facce, ruotati di 180 gradi l'una rispetto all'altra, che si attraversano senza
sbavare.
Il cursore muove l'intero mazzo; il pulsante lo fa girare da solo. È l'unica parte della pagina che ha bisogno di uno script, e sono venti righe.
.mazzo { transform-style: preserve-3d;
transform: rotateY(calc(var(--giro) * 1deg)); }
.carta { transition: transform .2s; }
.carta:hover { transform: translateZ(40px); }
Scroll-driven animations
Un'animazione CSS tradizionale ha una durata in secondi. Una scroll-driven
animation ha una durata in pixel: la barra in cima alla pagina non è gestita da uno
script, è un scaleX legato allo scorrimento del documento.
Anche i quattro riquadri qui sotto si accendono quando entrano nel riquadro visibile:
animation-timeline: view() segue la posizione dell'elemento, non il tempo.
Se il browser non conosce la proprietà, resta tutto visibile e fermo — nessun contenuto
sparisce.
Il riquadro tocca il bordo inferiore.
L'opacità cresce insieme alla posizione.
Al centro, l'animazione è completa.
Oltre il bordo superiore, resta ferma.
.passo {
animation: apparizione linear both;
animation-timeline: view();
animation-range: entry 10% cover 35%;
}
Spazi colore moderni
color-mix() mescola due colori in uno spazio percettivo, oklch()
descrive la luminosità come la vede l'occhio. Il risultato è che possiamo cambiare due
variabili e avere una scala coerente di tinte, bordi e superfici senza scrivere sei
colori a mano.
Scegli un'atmosfera: il riquadro ricalcola sfondo, testo e quattro campioni derivati. Le variabili sono le stesse; cambiano solo i loro valori.
Superficie
Due variabili, sei colori derivati.
.mood { --a: oklch(88% .04 120); --b: oklch(42% .09 140); }
.mood-vista {
background: linear-gradient(135deg, var(--a), var(--b));
color: color-mix(in oklab, var(--b) 80%, black);
}
Fine del foglio
Sei regole, un solo file CSS, un documento che si spiega mentre lo leggi. Il resto del laboratorio è dall'altra parte: una dashboard da costruire a mano e una tela che risponde alla voce.