Distortion✨ Premium

Chrome Reflection

Polished-metal pill button: on hover or focus, a slanted white shine sweeps across its upper half, then sweeps back when you leave it.

CSSMetalShine

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Distortion has 31 effects, including 5 free. Explore the category →

3 usage examples

“Make an offer” button on a classic motorcycle listing (Garage Vorbrenne) — Chrome Reflection example 1

① “Make an offer” button on a classic motorcycle listing (Garage Vorbrenne)

WhenOn the page of a restored 1971 twin, below the mileage and the price, the chrome button sweeps its shine when the mouse comes near or the keyboard reaches it.
WhyPolished metal echoes the bike's chrome and draws the eye to the page's only action, with no loud colour on a dark background.
Settings--chm-pad: 12px 22px, --chm-font: 19px, shine slowed to 0.7 s (--chm-speed), gold outline #d6a75c. For the capture, the scene gives and removes focus to the button every 1.6 s, a state the sold CSS handles.
Selection keys of an online jukebox (Dovranne Diner) — Chrome Reflection example 2

② Selection keys of an online jukebox (Dovranne Diner)

WhenEight keys A1 to B4, each with a song title; the shine passes over the hovered key, and a click puts the song “now playing” on the display.
WhyMetal keys echo the front of a real jukebox; the shine following the mouse from key to key makes you want to press.
SettingsOne root for the eight buttons, laid out as a 4-column grid by the page's CSS, --chm-pad: 7px 8px, --chm-font: 19px, --chm-radius: 14px, 58 px tall buttons on two lines (code and title). The display is updated by the page.
Menu of a karaoke screen driven by a remote (Chantevaux) — Chrome Reflection example 3

③ Menu of a karaoke screen driven by a remote (Chantevaux)

WhenOn the room's screen, three large keys “Solo”, “Duet” and “Scores”; the remote's arrows move focus and the shine passes over each key reached.
WhyOn a TV screen, focus is the only landmark: a shine sweeping the chosen key can be seen from across the room, better than a plain outline.
Settings140 × 84 px keys, --chm-font: 19px, --chm-radius: 22px, pink glow added by the page on the focused key. In the capture, the page sends a right arrow every 1.1 s to simulate the remote.

How it works

The .chm-btn is a real <button>. Its chrome look comes from a vertical gradient of white, light grey, mid grey in the middle, then light grey and white, finished with three shadows: a drop shadow under the button, a light line at the top and a dark line at the bottom, inside. A plain #d4d4d4 colour is declared under the gradient in case it doesn't render.

The shine is the ::before pseudo-element: a band as wide as the button and half as tall, in a transparent, 80% white, transparent gradient, slanted by 25°. It waits outside the button, on the left (left: -100%). On hover or focus, it moves to left: 200% in 0.5 s (--chm-speed): you see it sweep the top of the button once.

It is a transition, not a loop: when hover or focus ends, the shine travels back from right to left. While the mouse stays on it, nothing moves. Overflow is clipped by overflow: hidden.

Accessibility

  • Real button: <button type="button"> with its real text, activated with Enter and Space, announced as a button by screen readers.
  • Keyboard: focus triggers the same shine pass as hover, and an outline (--chm-ring) appears when focus comes from the keyboard. In Safari, the Tab key doesn't stop on buttons unless the “Press Tab to highlight each item” option is on (measured in WebKit); that's a browser setting, not the effect.
  • Touch: tapping the button triggers the shine pass (measured in Chromium, Firefox and WebKit with an emulated touch screen).
  • Reduced motion: with prefers-reduced-motion: reduce, the shine no longer slides; on hover or focus it shows still over the top half of the button, at 55% opacity.
  • Contrast: the #1a1a1a text sits in the middle of the button, where the metal is darkest (#737373): the ratio there is 3.7:1. That is enough for the bundled 1.25rem bold text (large text under WCAG, 3:1 threshold), not for smaller text: keep at least 18.7 px bold, or edit the gradient to lighten its middle.

Browser compatibility

CSS only, no JavaScript. Measured in Chromium 151, Firefox 153 and Playwright's WebKit 26.5: 0 errors, two independent copies, hover, focus, touch, 390 px and reduced motion. The copy-paste checker no longer reports “invisible text” since the fallback colour was added. Minimum versions per @mdn/browser-compat-data: CSS variables set the floor (Chrome 49, Firefox 31, Safari 9.1).

Chrome 49+✓ Full (measured in version 151)
Firefox 31+✓ Full (measured in version 153)
Safari 9.1+✓ Full; Tab stops on the button only if Safari's keyboard setting allows it (measured in WebKit)
Edge 16+✓ Full
Safari iOS 9.3+✓ Full, shine on tap (measured in touch WebKit)
Chrome Android 49+✓ Full (Chromium engine)

Without :focus-visible (before Safari 15.4 and Chrome 86), the focus outline doesn't show; the shine still passes on focus.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0264-root"><button class="chm-btn" type="button">CHROME</button></div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--chm-pad 20px 50px Button padding (vertical, then horizontal).
--chm-font 1.25rem Text size.
--chm-radius 50px Corner rounding: 50px gives a pill, 12px a rectangular button.
--chm-speed .5s Duration of one shine pass, there and back.
--chm-text #1a1a1a Text colour; stay with a very dark shade to keep contrast on the metal.
--chm-ring #e5e5e5 Outline colour on keyboard focus.
--chm-bg and --chm-min-h #0a0a0f and 300px Root background and minimum height; transparent and 0 to place the button in your page.

FAQ

Yes: each .chm-btn has its own shine. The root is a centred flex container; change its layout (grid, column) in your CSS if needed.
Because it is a CSS transition: when hover ends, the left property returns to its starting value with the same duration. For a single pass, set transition: none on .chm-btn::before outside hover and keep the transition in the :hover rule.
Yes: the chm-btn class works on an <a href>, since the shine also follows :hover and :focus. Add display: inline-block and text-decoration: none to the link.