Web Liquid Glass
Un material de vidrio de producción para sitios web, extraído de un sitio en vivo con Next.js + Tailwind. El código fuente completo está en reference/:
reference/liquid-glass.css: todo el material (tokens, superficie, variantes, vidrio con forma, refracción, degradación). Aproximadamente 2200 líneas con comentarios largos que explican cada valor. Lee la sección que necesites en lugar de todo el archivo.reference/glass.tsx: el componente React<Glass>y el filtro de refracción SVG.reference/glass-specular.tsx: el brillo especular que sigue al puntero y a la inclinación.
La referencia importa dos ayudantes del sitio (cn y LITE_CLASS de un módulo de modo ligero). Reemplázalos con el propio cn/clsx del proyecto y un nombre de clase para "efectos desactivados". Las reglas nombradas sky-*, kiosk-* y los selectores relacionados con oración son ejemplos específicos del sitio de variantes. Elimínalos o úsalos como patrones.
Qué es el vidrio
El vidrio tiene cuatro partes. Una versión web se ve barata cuando solo incluye la primera:
- Material: desenfoque (blur) Y un aumento de saturación (alrededor del 200%). Por debajo del ~150% se lee como plástico gris. Añade un aumento de brillo y una reducción de contraste para que el contenido ocupado detrás se difumine en un lavado suave.
- Borde: una línea brillante y fina donde la luz incide en el borde, más tenue en el borde opuesto. El desenfoque sin un borde nunca se lee como vidrio.
- Brillo: un destello especular suave dentro del borde superior.
- Profundidad: una sombra amplia, muy suave y de baja opacidad, no una sombra de tarjeta apretada.
La refracción (el contenido se curva en el borde) es una quinta parte, y la única que la web no puede hacer de manera económica. Necesita backdrop-filter: url(#svg-filter), que funciona solo en Chromium.
Dónde va el vidrio
Pon vidrio en la capa de navegación (barras, navegaciones en cápsula, controles flotantes, paneles), no en el contenido del cuerpo. El contraste del texto sobre vidrio depende de lo que se desplace detrás, por lo que no se puede garantizar. Mantén las tarjetas opacas como valor predeterminado para el contenido y haz que el vidrio sea opt-in por superficie (.lg).
Reglas que cuestan tiempo real
- El CSS del vidrio debe estar en el mismo archivo que
@tailwind base, dentro de@layer. Tailwind resuelve@layerpor archivo, por lo que un archivo CSS separado da error con@layer base. Eliminar el envoltorio hace que las reglas no tengan capa, y las reglas sin capa vencen a toda utilidad de Tailwind..lg { position: relative }entonces sobrescribe silenciosamentefixeden un nav. - Nunca escribas
--x: calc(var(--x) * 0.7). Es un ciclo: inválido en tiempo de valor calculado, cae silenciosamente al valor heredado sin error. Usa una segunda variable (--lg-clarity-bump,--lg-press). - Una superficie de vidrio tiene exactamente un borde, y
::beforelo dibuja. Dos bordes (un borde::beforemás biseles conbox-shadowinset, o una sombra extendida fuera de la caja del borde) dan un "doble borde" que ningún ajuste de alfa corrige. corner-shapeno se hereda. Concorner-shape: squircleen la superficie, cada pseudoelemento que dibuja en el borde necesita TANTOborder-radius: inheritcomocorner-shape: inherit, o el borde sigue una curva diferente a la del cuerpo.- No uses
backdrop-filteren vidrio anidado dentro de vidrio. Muestrea un fondo ya teñido y se vuelve turbio. Un chip de selección dentro de una barra de vidrio (.lg-chip) es una lente teñida sin desenfoque propio. - No animes una propiedad personalizada heredada en
:root. Invalida el estilo de todo el documento: aproximadamente 11.6 ms por fotograma en una página con 60 superficies, frente a 2 ms escribiendo el mismo valor por elemento. - Las barras se vuelven a desenfocar en cada fotograma de scroll. Dale a
.lg-barun radio de desenfoque más pequeño máscontain: paint. Si un dispositivo aún se traba, establece--lg-blur-bar: 0px; el borde y el brillo llevan la mayor parte del aspecto. - No aplastes el vidrio esmerilado para arreglar un fallo. Una barra de "color sólido" casi opaca pierde el aspecto. Encuentra la causa geométrica en su lugar (máscaras que adelgazan el cuerpo en el borde, un borde duplicado).
- Una lente de refracción SVG nunca debe muestrear más allá de su propia caja. Chrome devuelve transparente allí y el contenido original se muestra como fantasmas.
Safari y iPhone
WebKit soporta backdrop-filter pero rechaza los filtros SVG dentro de él, por lo que Safari obtiene menos que Chrome: sin refracción, nunca. Lo que Safari puede refractar es su propia barra de herramientas. Establece viewportFit: "cover" para que la página se ejecute debajo, luego env(safe-area-inset-*) se vuelve obligatorio en la navegación y el pie de página.
Accesibilidad y fallbacks (inclúyelos siempre)
Cada superficie debe degradarse a un tinte casi opaco que se vea similar y no cueste nada por fotograma:
@media (prefers-reduced-transparency: reduce)@supports not (backdrop-filter: blur(1px))@media (prefers-contrast: more): un tinte más fuerte y un borde sólido- una clase raíz como
.lg-offque mate todas las superficies de vidrio a la vez (para un interruptor de usuario o un modo de bajo consumo)
Dale a las barras su propio tinte máximo más alto (--lg-tint-max-bar) para que los enlaces de navegación mantengan contraste de texto cuando el contenido se desplaza debajo de ellos.
Cómo aplicar
- Copia el bloque de tokens y la sección de superficie de
reference/liquid-glass.cssen el archivo CSS principal del proyecto, dentro de sus bloques@layerexistentes (regla 1). - Asigna los tokens de color a la paleta del proyecto. La referencia usa tokens de estilo shadcn
hsl(var(--card)). - Usa
<Glass>dereference/glass.tsxo las clases simples.lg,.lg-bar,.lg-nav,.lg-pane,.lg-chipy.lg-refract. - Añade el brillo especular de
reference/glass-specular.tsxsolo donde valga la pena su costo (controles principales, el nav principal), y respetaprefers-reduced-motion. - Verifica en Chrome Y Safari, en modo claro Y oscuro, sobre una foto ocupada y sobre texto plano.
Controles listos para usar: Glisse
Glisse de Kelvin Zhang (npm install glisse, MIT, React 18+, sin otras dependencias) incluye controles interactivos de vidrio líquido con el comportamiento de lente al presionar ya incorporado: Button, Switch, Slider, TabBar, SegmentedControl, Menu, Input, SearchField y una superficie Glass simple. Sus estilos son inyectados por el paquete JS, por lo que no hay un archivo CSS que importar.
Cuándo usar cada uno:
- Glisse para controles: interruptores, sliders, barras de pestañas y controles segmentados cuyo pulgar se eleva a una lente mientras se arrastra. Construir eso a mano son días de trabajo.
- Este material para superficies: barras de navegación, navegaciones en cápsula, paneles, hojas, tarjetas sobre fotos y cualquier cosa que deba coincidir con un sistema de diseño existente o un tema de Tailwind.
Trampas al combinarlos:
- Ambos usan el prefijo
lg-. Glisse define.lg-glass,.lg-button,.lg-tab-bary las variables--lg-blur,--lg-tint,--lg-rimy--lg-filter, que chocan con los tokens de este material. En una página que use ambos, renombra el prefijo de este material (por ejemplo, aylg-) o delimita Glisse dentro de un envoltorio que reinicie esas variables. De lo contrario, cada uno reajusta silenciosamente al otro. - El modo oscuro de Glisse se activa con
data-theme="dark"oprefers-color-scheme, no con la clase.darkde Tailwind. Con modo oscuro basado en clases, establecedata-themeen<html>junto con.dark, o Glisse se queda en modo claro. - Glisse maneja
prefers-reduced-motionpero noprefers-reduced-transparencyniprefers-contrast. Añade los fallbacks de la sección de accesibilidad de este skill alrededor de los controles de Glisse. - El
.lg-glassde Glisse ya dibuja un borde con unbox-shadowinset. No añadas un borde::beforeencima de él (regla 3: solo un borde).