glass-button

A real <button> under a WebGL2 render of thick glass with a procedural effect inside: fire or water, in four status colours. Hover, press, tab to it. Everything below is the same component at different sizes and settings.

Take Action →
WebGL2
Take Action →
CSS fallback

Status modes

The status attribute recolours the effect, the glass rim and the floor glow and shows a matching icon; unknown is the default. Changing it crossfades the palette. icon="none" hides the icon; slot="icon" supplies your own.

Healthy Warning Trouble Unknown

Water

effect="water" swaps the combustion for a lit liquid: a waving surface with a specular crest, caustics, rising bubbles and a faint mist. Status palettes tint it; without a status it is aqua. Switching effects crossfades. Hover raises the waves; pressing sends a ripple across.

Dive In → Healthy Warning Trouble

States

Idle burns low. Hovering raises the effect, the lower glass illumination and the rim brightness over a few hundred milliseconds. Moving the pointer slides the key light across the glass. Pressing compresses the pill slightly and pulses the effect, then relaxes with no bounce. Use the controls under the hero button above to hold these states.

Sizes

The shader works in units of pill height, so rims, refraction and effect scale stay proportional. The effect buffer keeps a fixed texel density per pill height instead of stretching.

Take Action → Take Action → Take Action →

Mobile width

An explicit width on the host stretches the pill; the effect still scales with the height.

Take Action →

Reduced motion

With prefers-reduced-motion: reduce the effect is frozen in place and the renderer only draws while a hover or press state is easing. The design stays intact. The toggle below forces it via the reducedMotion property.

Take Action →

CSS fallback

When WebGL2 is unavailable the element sets data-renderer="css" and the shadow stylesheet paints a simplified glass and glow. Setting that attribute yourself forces the fallback, as here.

Take Action → Dive In → Healthy Warning Trouble Unknown

Usage

<script type="module" src="glass-button.js"></script>

<glass-button level="1.2" bloom="0.8">
  Take Action →
</glass-button>

<script type="module">
  const el = document.querySelector('glass-button');
  el.addEventListener('click', () => console.log('clicked'));
  el.intensity = 1.3;                 // property ↔ attribute
  el.params = { turbulence: 1.4 };        // merge several at once
</script>
Background