Refractive glass effects for React components
Refractive is a higher-order React component that adds refractive glass effects via SVG filters and backdrop-filter.
View on GitHub
View package source code in our hash monorepo
View on npm
or use npm install @hashintel/refractive
Achieving refractive lighting effects that are realistic, performant, or cross-browser compatible is today a difficult challenge. Achieving all of these things simultaneously, while providing graceful fallbacks to stylistically similar alternatives where otherwise unsupported, is unheard of. The goal of the refractive library is to enable exactly this.
Two <Filter> components can be found in the refractive library, to create the SVG filter that provides the refractive effect to components.
lib/filter.tsx: Calculates an image for the whole displacement map and specular. This is useful for components like Switch and Slider, where refractive parts are fixed-size.lib/flexible-filter.tsx: Calculates the same images, but splits them into multiple tiles, to cover larger areas. This is useful for components like Card and Modal, where refractive parts can be large and dynamic in size.Presently all image calculation is performed client-side, and not cached. Furthermore, every component instantiates its own <Filter> component. This may be optimized in the future, including by generating these images at build-time and proactively caching them.
A flexible filter system splits images into nine parts to handle dynamic sizing while preserving corner details. This approach allows corners to maintain their shape while middle sections can stretch to accommodate any size content.
The refractive package is in early beta, and various known limitations exist in the current published version:
BezelWidth needs to be lower than the Radius property. This requires rework of the displacement map generation logic.For now, only Chrome supports the CSS features required to render "true" refraction. In all other cases, graceful fallback mechanisms are needed for providing commensurate, or at least visually comparable, user experiences.
No single solution exists for achieving this, as fallbacks vary depending on the specific component in question and its usage context. However, the following general strategies may be used:
Whether for personal preference, accessibility, or performance reasons, offering users the option of whether or not to employ refractive-style lighting effects, or transparency in general, may be desirable.
Where practical and appropriate, users should be provided with a preferences toggle or slider in an application's appearance settings enabling them to switch between fully refractive ("Liquid Glass") and fallback designs.
The Refractive library is being primarily developed by Chris Feijoo at HASH.
See Liquid Glass in the Browser: Refraction with CSS and SVG for an introduction to the original research that led to this library's creation.