- En partant des interfaces frosted acrylic de Forza Horizon 3 et Forza Motorsport 7, l’article résume le processus permettant de reproduire sur le web un effet similaire de panneau en verre avec HTML/CSS/JavaScript
- Le cœur de l’effet est le flou gaussien ; il faut utiliser à la fois
backdrop-filteren CSS et-webkit-backdrop-filterpour iOS afin de réduire les différences entre navigateurs - Comme un simple flou peut donner un rendu plat, on ajoute de la profondeur aux bords et du subsurface scattering avec
box-shadow: inset, puis une ombre classique pour donner l’impression que le panneau flotte au-dessus de l’arrière-plan - Les reflets de surface sont implémentés en plaçant une image de rayons lumineux dans un calque séparé ;
background-attachment: fixedou JavaScript permettent de simuler des reflets dynamiques alignés avec le déplacement du verre - L’interface finale combine les calques
.glass,.lightet.drag-me, puis ajoute des coins arrondis, du clipping et une couleur d’arrière-plan semi-transparente pour obtenir un composant de verre copiable
Un effet de panneau en verre inspiré des interfaces de jeux
- L’objectif est de reproduire en HTML le design frosted acrylic issu de l’expérience de développement des interfaces de Forza Horizon 3 et Forza Motorsport 7
- Le résultat est un panneau de verre déplaçable, combinant flou d’arrière-plan, profondeur des bords, reflets lumineux, coins arrondis et calque de couleur semi-transparent
- Une recette finale directement copiable est fournie au début, puis chaque effet est construit étape par étape
Créer le flou d’arrière-plan avec backdrop-filter
- La clé d’un bon effet frosted glass est le flou gaussien, qui rend l’arrière-plan flou pour donner l’apparence d’un écran translucide
- En CSS, il s’implémente en appliquant
bluràbackdrop-filter - L’élément de verre de base part d’un simple
divavec une classe.glassbackdrop-filter: blur(10px)-webkit-backdrop-filter: blur(10px)
- Sur iOS,
-webkit-backdrop-filterest nécessaire sauf à modifier en profondeur des réglages spécifiques - Comme
backdrop-filtern’est pris en charge par les navigateurs que depuis peu, les utilisateurs d’Internet Explorer ne pourront pas voir la démo
Créer de la profondeur avec les bords et les ombres
- Avec seulement
backdrop-filter: blur(10px), le verre peut paraître plat et monotone - Les bords sont réalisés avec
box-shadow: insetplutôt qu’avecborder: 1px solidborderinflue sur la taille de l’élément et le positionnement de ses enfants- Avec
box-shadow: inset, les enfants peuvent remplir naturellement la zone de contenu du verre sans ajustements comme des marges négatives
- Deux inset shadows blanches semi-transparentes servent à représenter les bords du verre
- La première shadow représente l’arête du verre visible de l’extérieur ; dans l’exemple, elle apparaît sur les bords inférieur et gauche
- La seconde shadow représente l’arête visible à travers le verre ; dans l’exemple, elle apparaît sur les bords supérieur et droit
- Comme la lumière est atténuée lorsqu’elle traverse le verre, l’arête visible à travers celui-ci est réglée de façon plus douce et plus transparente
- Ajouter une
box-shadowsombre classique permet de donner l’impression que le verre flotte physiquement au-dessus de l’arrière-plan
Diffusion de la lumière et reflets de surface
- L’impression de lumière qui se diffuse à l’intérieur du verre est une version simplifiée du
subsurface scattering - L’implémentation utilise de nouveau
box-shadow: inset- Effet de diffusion court :
inset 0px 0px 10px 5px rgba(255, 255, 255, 0.025) - Effet de diffusion plus profond :
inset 0px 0px 40px 5px rgba(255, 255, 255, 0.025)
- Effet de diffusion court :
- Cet effet se voit mieux lorsqu’on fait glisser le verre au-dessus d’un arrière-plan sombre
- En plus de l’impression de réfraction due au flou de l’arrière-plan, on ajoute aussi la propriété de réflexion de la lumière sur la surface du verre
- Les reflets lumineux sont implémentés en mélangeant une image de rayons lumineux à l’arrière-plan
- Il existe un tutoriel YouTube et une explication textuelle pouvant servir de référence pour créer une image similaire
- Si l’image est placée directement dans
background-imagesur l’élément.glass,backdrop-filterla rend floue ; on utilise donc un calque séparé comme::before
Transformer des reflets statiques en reflets dynamiques
- Ajouter seulement l’image de rayons lumineux crée un reflet, mais lorsque le verre se déplace, la lumière peut sembler fixée à la surface du verre
- La méthode en CSS pur consiste à ajouter
background-attachment: fixedà::before- L’implémentation est simple, mais peut ne pas fonctionner sur toutes les plateformes
- Pour que cela fonctionne sur toutes les plateformes, JavaScript simule
background-attachment: fixed- Manipuler directement
::beforeen JavaScript est inefficace ; on utilise donc un élémentdiv.lightséparé - L’attribut
data-js-background-attachment-fixedest ajouté à l’élément cible
- Manipuler directement
- À chaque frame d’animation, JavaScript lit la valeur de
getBoundingClientRect()pour l’élément cible, puis met à jourbackground-positiondans la direction opposée à sa position dans le viewportbackgroundPositionX = -clientRect.xbackgroundPositionY = -clientRect.y
- La boucle répétée s’exécute avec
requestAnimationFrame
Structure HTML/CSS finale
- Le HTML final de la version JavaScript place
.lightpour les reflets lumineux et.drag-mepour le calque texte/couleur à l’intérieur de.glass
Drag Me
.glassgère la forme de base et les effets visuels du panneau de verre- Applique le flou d’arrière-plan avec
backdrop-filteret-webkit-backdrop-filter - Applique les bords, l’ombre et les effets de diffusion avec plusieurs
box-shadow - Utilise
position: relativepour permettre aux calques enfants de remplir la zone du parent - Applique des coins arrondis avec
border-radius: 5px - Découpe les éléments enfants avec
overflow: hiddenpour éviter qu’ils débordent hors des coins arrondis
- Applique le flou d’arrière-plan avec
.lightutilise l’image de rayons lumineux comme arrière-plan répétébackground-image: url(path/to/light.png)background-repeat: repeatbackground-size: 750pxopacity: 0.075- Remplit tout le parent avec
position: absoluteet des offsets0sur les quatre côtés - S’affiche derrière les autres enfants avec
z-index: -1
.drag-mecentre le contenu et crée un calque de verre semi-transparent colorédisplay: flexalign-items: centerjustify-content: centerheight: 30pxbackground-color: rgba(12, 13, 14, 0.75)
Différences de la version sans JavaScript
- La version sans JavaScript utilise
.glass::beforeau lieu d’un élément.lightséparé - Elle applique l’image de rayons lumineux à
::beforeet implémente un reflet fixé à l’écran avecbackground-attachment: fixed - Cette méthode ne fonctionne pas sur toutes les plateformes ; la version JavaScript la complète en mettant directement à jour
background-position
1 commentaires
Avis sur Hacker News
Esthétiquement, j’aime vraiment beaucoup, mais il y a des aspects qui ne collent pas physiquement sur les bords.
Du point de vue d’un développeur embarqué, ça me paraît un peu gaspilleur. On dirait que chaque client calcule à chaque fois un filtre de flou « coûteux » pour le mélanger avec une version floutée de l’image d’arrière-plan.
Comme ça utilise le GPU et que c’est optimisé, le coût final n’est peut-être pas si élevé, mais le développement web actuel donne globalement l’impression de devenir beaucoup trop lourd. Même des sites simples mettent 5 secondes à charger et délèguent des traitements lourds au client ; bien sûr, ce n’est pas la faute de l’auteur de cet article.
Ayant grandi à l’époque des modems 14,4k, j’ai l’habitude de considérer que la bande passante réseau est bien plus rare et coûteuse que le temps CPU.
Si l’on peut le calculer facilement côté client, je trouve plus gaspilleur de télécharger toute une image via Internet. Pour obtenir cette image, on fait travailler des routeurs, des serveurs et même des disques distants ; tout cela pour éviter un traitement sur des données déjà présentes dans la RAM du client, ça me semble encore plus dommage.
Donc soit le divertissement lui-même est un gaspillage, soit, s’il ne l’est pas, utiliser davantage de calcul pour l’améliorer me paraît acceptable.
Pour redessiner ce qui change dans une UI, il faut de toute façon du calcul GPU, et un flou simple peut s’ajouter assez efficacement. C’est probablement moins coûteux que d’animer des objets DOM non optimisés en calques GPU.
Quand on voit que même les sites les plus simples chargent aujourd’hui plus de 1 Mo de JavaScript et une foule de traceurs qui consomment du CPU, un flou à but esthétique est très loin dans la liste des gaspillages.
Avec beaucoup d’images haute résolution, la bande passante réseau réelle est limitée, et surtout sur mobile avec une mauvaise couverture sans fil, c’est clairement moins performant que du calcul local. Ce qu’on peut faire aujourd’hui uniquement avec CSS/WebGL est étonnant ; autrefois, ce genre d’effet demandait beaucoup de hacks et de contournements.
Indépendamment du fait que l’action elle-même soit du gaspillage ou non, cette façon de penser révèle un problème plus profond de la société. Pourquoi en a-t-on besoin, et pourquoi considère-t-on que l’absence de cela est mauvaise ?
Vu l’ampleur des problèmes sociaux actuels, qui se soucie vraiment de savoir si un panneau d’UI est flouté ou non ?
En essayant de recréer l’effet Windows 7 Aero Glass sur Android pour voir ce qu’on pouvait faire avec la nouvelle API de shaders, j’ai extrait une texture de « rayons lumineux » similaire.
Le résultat est devenu très proche de cet article, sauf que je n’ai pas ajouté d’ombre interne et que j’ai légèrement augmenté la saturation de l’arrière-plan flouté.
https://mastodon.social/@grishka/110524476584503201
Honnêtement, celle créée pour le tutoriel n’est pas si extraordinaire. J’aime les lignes plus nettes de la version Windows 7.
J’ai aussi pensé à ajuster la saturation et je l’ai vu dans d’autres exemples, mais j’ai décidé de ne pas l’utiliser dans l’article. Comme l’image de lune utilisée n’avait pas beaucoup de couleurs, cela n’aurait probablement pas fait une grande différence. Ceux qui créent leur propre effet de verre devraient aussi expérimenter avec la saturation.
Le travail en lui-même est excellent, et la présentation sous forme de démo interactive est réussie. C’est amusant de faire glisser la fenêtre sur la lune.
En revanche, je n’aime pas l’usage de l’effet verre dépoli dans la conception d’interfaces utilisateur, et quand il a été ajouté à Mac OS, je l’ai ressenti comme une régression. Les designers se laissent trop facilement séduire par cet effet, alors qu’en pratique il n’est jamais idéal, surtout lorsque le contenu derrière le panneau est dynamique ou généré par l’utilisateur.
C’est un peu l’équivalent du métal brossé des années 2010, et il est surprenant qu’il se soit échappé de Windows Vista pour se répandre partout.
Bien sûr, le design affecte aussi la fonction, mais son objectif principal est de rendre l’expérience utilisateur plus agréable.
Je trouve que le skeuomorphisme rend les interfaces plus agréables que la tendance minimaliste des dix dernières années et plus, qui a tout aplati. Les ornements visuels imitant les surfaces et matériaux du monde réel ajoutent de la familiarité et de l’accessibilité. Même d’un point de vue pratique, le flat design rend plus difficile la distinction entre les éléments et leurs états, alors qu’à l’époque des boutons 3D, du métal brossé et du verre dépoli, c’était beaucoup plus clair.
Je pense que le pendule est en train de repartir dans l’autre sens. De plus en plus de designers évitent l’apparence plate, donc j’espère voir renaître des UI plus humaines.
Le flou n’est généralement pas la bonne réponse, mais parfois c’est le bon choix.
En 2008, avant que CSS ne prenne en charge
backdrop-blur, j’avais déjà fait une expérimentation CSS pour obtenir un effet similaire : https://webdev.andersriggelsen.dk/aero/Le principe consistait à appliquer un effet de verre sur une image d’arrière-plan fixe et préalablement floutée : https://webdev.andersriggelsen.dk/aero/bgl.jpg
C’est bien plus performant qu’un flou gaussien en temps réel, mais l’inconvénient reste le même : impossible d’autoriser des images d’arrière-plan dynamiques
Cela permettait d’obtenir un effet de verre même dans un cadre pouvant bouger dynamiquement. Je ne me souviens plus si j’utilisais une iframe, il faudrait que je retrouve le code, mais vu l’époque, il y a de fortes chances que oui
Je suis sous Windows 10 19045.5131, avec Chrome à jour, Version 131.0.6778.86 (Official Build) (64-bit)
La prouesse technique est chouette, mais je trouve que c’est une mauvaise UX
Le contenu dans des panneaux translucides est plus difficile à lire ou à comprendre que sur un fond uni et cohérent, avec un contraste plus faible et irrégulier par rapport à l’arrière-plan. En plus, si quelque chose bouge dessous, cela peut distraire et désorienter
Une bonne intégration devrait ajuster l’intensité de l’effet pour ne pas surcharger l’UI, vérifier la prise en charge des fonctionnalités afin d’éviter d’ajouter des ornements quand le flou n’est pas disponible, et vérifier les capacités d’affichage et vidéo pour ne pas le rendre sur des appareils dont le GPU risque d’être insuffisant
Il faut aussi tenir compte des préférences utilisateur pour proposer un aplat très contrasté aux personnes que les arrière-plans complexes gênent, limiter l’étendue de l’effet et des ombres selon l’espace disponible, et ajuster le flou et l’opacité en fonction de la complexité et du contraste de l’arrière-plan sous la zone floutée
Il faut également s’assurer que le flou et les ombres s’adaptent de façon réactive à la typographie. L’UX consiste fondamentalement à concevoir la manière dont l’utilisateur vit son interaction avec l’application dans son ensemble ; elle ne se joue pas sur un choix de style isolé
Cela garantissait la lisibilité du texte même dans le cas extrême d’un arrière-plan noir. En CSS, on peut le reproduire avec la propriété
text-shadowEn revanche, il a davantage sa place dans les jeux. Il peut notamment convenir aux HUD, quand on ne veut pas masquer l’arrière-plan, qui est la zone principale avec laquelle l’utilisateur interagit
Obtenir un bon contraste est un défi pour n’importe quel élément de design, qu’il s’agisse d’un aplat ou d’un effet de verre
L’idée que ce qui se passe en arrière-plan soit distrayant et désorientant est aussi très subjective. On peut réduire la translucidité du verre comme on réduit l’opacité d’un aplat
Cette critique me paraît difficile à tenir comme objectivement vraie, et il existe des façons d’intégrer cet élément de design tout en évitant ces problèmes. La capture d’écran de Forza a l’air correcte, et en pratique l’arrière-plan ne m’a pas paru distrayant. En contrepartie, on obtient une UI plus intéressante et visuellement plus agréable qu’avec un fond uni. C’est peut-être plus important dans les jeux vidéo, mais cela peut aussi être utilisé avec élégance dans les OS et le design web
Si l’on a besoin de beaucoup de contexte, le flou est un mauvais choix ; si l’on n’a besoin d’aucun contexte, c’est aussi un mauvais choix
Mais parfois, c’est un excellent choix
L’exemple interactif est bien, mais cela aurait été encore mieux avec un toggle permettant de comparer côte à côte avec l’étape précédente, ou de basculer entre les deux
Dans la plupart des étapes, l’amélioration était trop subtile pour que l’on distingue vraiment la différence
Il y a une dizaine d’effets empilés ; à moins de viser une esthétique très exigeante, environ 7 d’entre eux sont de trop
Une couleur de fond, du flou, et éventuellement une ombre ou une bordure suffisent
Rien qu’à la troisième étape, avec seulement le flou et l’ombre, on obtient déjà un morceau de verre assez convaincant. Personnellement, je recommanderais d’y ajouter une image statique de reflets lumineux. Je ne pense pas que la plupart des applications aient besoin de l’effet JavaScript complet. C’est amusant, mais cela peut distraire
Avec seulement le flou, l’ombre et les reflets lumineux, on peut déjà se rapprocher vraiment beaucoup de l’image Forza en haut
À mon avis, c’est l’une des raisons pour lesquelles tout le monde est passé au flat design. Windows Vista et les effets de verre étaient magnifiques, mais coûteux en calcul
Le flat design est controversé sur le plan esthétique et peut être plus difficile à utiliser que le design skeuomorphique, surtout pour les utilisateurs plus âgés [0][1]
Si le réalisme peut aider l’utilisabilité, alors employer ce genre d’effets sur le web me semble tout à fait justifié
[0]: https://www.tandfonline.com/doi/abs/10.1080/0144929X.2020.18...
[1]: https://www.sciencedirect.com/science/article/abs/pii/S01419...
n <= 3Je ne sais pas s’il s’agit d’un problème d’accessibilité, de performance, de maintenabilité ou d’autre chose
Comme CSS est de loin mon point le plus faible parmi les compétences de développement, je ne connais pas du tout les bonnes et mauvaises pratiques
C’est intéressant, on a vraiment l’impression d’avoir bouclé la boucle
L’une des premières démos CSS, une démo pour CSS 1, était justement un effet de verre dépoli : https://meyerweb.com/eric/css/edge/complexspiral/glassy.html
Honnêtement, c’est assez impressionnant. C’est toujours un plaisir de voir à quel point CSS peut être créatif et puissant
Cela dit, j’ai l’impression qu’il existe dans HTML/CSS un certain niveau que je ne comprendrai jamais. Cette démo en est le parfait exemple : cette personne est en train de créer une vitre givrée, alors que moi je n’arrive toujours pas à centrer un simple
divdivde plus était souvent une bonne idéeQuand on regarde la plupart des sites web modernes, on voit d’immenses piles de
div. Si l’on veut undivcentré, c’est relativement facile en créant à l’intérieur un autredivqui occupe tout l’espace dans lequel le centrerBeaucoup d’astuces visuelles reposent sur le même principe, mais cet exemple est très propre, ce qui le rend encore plus impressionnant
Ce n’est pas exactement du verre givré, mais j’ai essayé d’ajouter un effet de vitre dans la barre latérale de https://www.gyan.dev/ffmpeg/builds/