---
title: "A realistic hardware button in pure CSS"
description: "Recreating a physical, illuminated push-button — gunmetal bezel, recessed lit-glass panel, glossy sheen, and a colored light bloom — with two elements, layered gradients, and inset shadows. No images."
date: "2026-05-29"
tags: ["css", "skeuomorphism", "buttons", "frontend"]
---

Flat design won, and then it got boring. Every so often a button comes along
that looks like an *object* — machined metal, lit glass, a real press — and you
remember screens can pretend to be physical. Here's one, built from three
nested layers and a stack of gradients:

Press it — the glass sinks into the housing. No images, no SVG. Four ideas do
all the work.

## 1. The bezel is the outer element's padding

The metal frame isn't a border — it's the button's **padding**. A steep gray
gradient plus inset bevels turns that band into machined metal lit from above:

```css
.hw-btn {
  padding: 13px;                 /* this band IS the bezel */
  border-radius: 26px;
  background: linear-gradient(158deg, #5a5a62, #313137 13%, #1a1a1d 52%, #0a0a0b);
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.4),   /* bright top edge   */
    inset -1.5px 0 1px rgba(0,0,0,.55),     /* shadowed right    */
    inset 0 -2px 4px rgba(0,0,0,.7);        /* dark bottom inner */
}
```

The lit top edge + dark bottom is the whole trick for "metal" — it tells your
eye where the light is.

## 2. A black well, then convex glass

Don't sit the glass flush in the metal — float it in a **black recessed well**.
A middle layer with a near-black fill and a deep `inset` shadow gives the dark
margin all around the panel, so the glass reads as a separate part dropped into
the housing:

```css
.hw-btn__well {
  padding: 13px;                 /* the dark margin */
  border-radius: 20px;
  background: linear-gradient(180deg, #050506, #121214);
  box-shadow: inset 0 4px 9px rgba(0,0,0,.9);
}
```

The glass itself is a **dark → bright → dark** vertical gradient. That symmetry
is what makes it look like a convex tube lit through the middle, rather than a
flat sticker:

```css
.hw-btn__glass {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--hw-color) 72%, #000), var(--hw-color) 26%,
    color-mix(in srgb, var(--hw-color) 52%, #fff) 52%, var(--hw-color) 74%,
    color-mix(in srgb, var(--hw-color) 72%, #000));
}
```

## 3. A pseudo-element is the sheen

Real glass has a hard reflection on its upper curve. One gradient pseudo-element
with an asymmetric `border-radius` fakes the bulge:

```css
.hw-btn__glass::before {
  content: ""; position: absolute; inset: 1px 1px auto 1px; height: 58%;
  border-radius: 12px 12px 46% 46% / 12px 12px 30px 30px;
  background: linear-gradient(180deg, rgba(255,255,255,.62), rgba(255,255,255,.06));
}
```

That elliptical bottom radius is what curves the highlight instead of cutting it
flat — the difference between "glossy" and "glass." A second pseudo-element
(`::after`) adds a soft, blurred **waterline reflection** across the lower third
— the bright band you see on real curved glass:

```css
.hw-btn__glass::after {
  content: ""; position: absolute; left: 7%; right: 7%; bottom: 13%; height: 18%;
  border-radius: 100%; filter: blur(1.5px);
  background: linear-gradient(180deg, rgba(255,255,255,.5), transparent);
}
```

## 4. It emits light, and it presses

An outer `box-shadow` in the same hue spills a bloom onto the surface below, so
the button looks *on*. And the press is physical — drop it 2px and deepen the
glass shadow so the light pushes inward:

```css
.hw-btn {
  box-shadow: /* …bevels… */,
    0 10px 55px -6px color-mix(in srgb, var(--hw-color) 50%, transparent); /* bloom */
}
.hw-btn:active { transform: translateY(2px); }
.hw-btn:active .hw-btn__glass { box-shadow: inset 0 5px 10px rgba(0,0,0,.6); }
```

## Takeaways

- A "metal" surface is really just a **lit top edge + dark bottom** over a gray
  gradient — direction of light is everything.
- Recess inner panels with an `inset` shadow so they sit *under* the frame.
- Curve a highlight with an **asymmetric `border-radius`** pseudo-element to fake
  glass.
- Derive every shade from one color with `color-mix`, add a same-hue bloom, and
  the button reads as a glowing physical object.

Recolor it and flip the arrow on the
[Hardware Button](/components/hardware-button) page.
