DEV Community

Cover image for React glass that refracts the page using Snell's law
Huynh Thanh Phuc
Huynh Thanh Phuc

Posted on

React glass that refracts the page using Snell's law

Meniscus demo showing a live refraction diagram and Newton's Opticks

Most "glass" UI is a blur, a transparent fill, and a bright border. I wanted a React component whose edges bend the page like a real lens, while still being practical to use in an app.
That became Meniscus, an MIT-licensed library and
interactive demo.

A curved rim becomes a displacement map

The surface has a flat center and a curved bezel. Its profile describes the height at each point across that rim. The profile's slope gives the angle where a ray hits the surface; Snell's law gives the angle inside the glass. From there, Meniscus calculates where the ray lands on the page and uses that offset to shift the backdrop.

The same surface normals drive the highlights, with one light angle shared across components. In the playground, you can drag a lens across a scanned plate from Newton's Opticks and change the rim profile, refraction strength, index of refraction, and light direction. The diagram updates as the lens moves.

What each browser actually draws

The rendering path matters. Chromium can apply an SVG displacement map inside backdrop-filter, so it refracts the live page. Safari and Firefox render a frosted version for a regular page backdrop. If you give the component an image, video, or canvas as its backdrop, Meniscus can refract that media through WebGL in those browsers too. This distinction is visible in the manual; I don't want a fallback described as live refraction when it is not.

Server rendering starts with the frosted appearance, and the supported refraction path takes over after hydration. The package supports React 18 and 19 and needs no stylesheet import.

From one surface to components

Install it with npm i meniscus, then start with a Glass:

import { Glass } from 'meniscus';

export function Toolbar() {
  return (
    <Glass radius="capsule" interactive>
      <button>Plates</button>
      <button>Search</button>
    </Glass>
  );
}
Enter fullscreen mode Exit fullscreen mode

The package also includes glass buttons, tabs, panels, text fields, selects, checkboxes, a loader, and a moving selection indicator. The component gallery has live examples and copyable code.

The 30-second demo gives a quick tour.

Top comments (0)