Expérience 02
Toutes les cartes de ce site sont des panneaux translucides. La recette tient en une ligne de CSS — mais si on se trompe d'ingrédient, on obtient du gris flouté, pas du verre.
Presque tout le monde écrit backdrop-filter: blur(20px) et
s'arrête là. Le résultat est décevant sans qu'on sache dire pourquoi :
ça fait sale, terne, plastique. Il manque un mot.
Regarde les deux panneaux ci-dessous. Même flou, même fond,
même bordure. Le seul écart est saturate().
Le même panneau, à un mot près
blur(20px)
saturate(100%)Sans saturation
blur(20px)
saturate(180%)Avec saturation
Celui de droite ressemble à du verre. Celui de gauche à une vitre sale. La raison est physique : flouter, c'est faire la moyenne des pixels voisins. Or la moyenne de couleurs vives est toujours plus terne que les couleurs d'origine — le rouge et le bleu voisins donnent un gris violacé. Le flou délave mécaniquement ce qu'il traverse.
Le vrai verre ne fait pas ça. Il diffuse la lumière sans lui retirer sa
couleur. saturate(180%) rend ce que le flou a pris.
Ce qu'il faut retenir : ce n'est pas le flou qui fait le verre, c'est la saturation restituée après le flou. Sans elle, l'effet retombe systématiquement — et on cherche en vain du côté du rayon de flou ou de l'opacité.
Réglage en direct
Panneau de verre
blur(20px) saturate(180%)Passe la saturation à 100 % : le panneau meurt instantanément, quel que soit le flou. Puis coupe l'arête lumineuse — c'est le troisième ingrédient.
Une vraie plaque de verre a une épaisseur. Sa tranche supérieure attrape la lumière et forme un liseré clair d'un pixel. C'est ce que simule cette ombre intérieure :
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22);
Un pixel blanc à 22 %, en haut seulement. C'est ridicule à écrire et c'est ce qui donne l'épaisseur — sans cette ligne, le panneau est une découpe plate posée sur le fond.
Sur la page d'accueil, la carte principale porte un arc de lumière qui tourne lentement. Le problème : CSS ne sait pas appliquer un dégradé à une bordure. La technique contourne l'obstacle.
.iris::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px; /* l'épaisseur du futur liseré */
background: conic-gradient(from var(--angle), …);
mask: linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
mask-composite: exclude; /* garde la couronne, jette le centre */
}
On pose un rectangle entièrement rempli du dégradé, puis on en
découpe le centre. Deux masques se superposent : l'un
couvre la boîte de contenu, l'autre la boîte entière ;
exclude ne conserve que leur différence — soit exactement
l'anneau de 1 px du padding. Ce qui reste est une bordure
en dégradé.
L'angle est animé via @property, qui déclare
--angle comme un vrai angle. Sans cette déclaration, le
navigateur traite la variable comme du texte et l'animation
saute de 0° à 360° sans passer par les valeurs
intermédiaires.
backdrop-filter floute ce qui est sous l'élément.
Sur un fond uni, l'effet est rigoureusement invisible — d'où le fond
coloré et rayé des démos de cette page.
@supports not (backdrop-filter: blur(1px)) {
.glass { background: rgba(20, 20, 24, .85); }
}