25 CSS Button Groups
17 / 25

All 25 in 25 CSS Button Groups

  1. 01CSS Split Button with Anchor-Positioned Popover Menu (Popover API, No JS)
  2. 02CSS Segmented Control with Motion-Path Comet Thumb (offset-path Arc Travel)
  3. 03CSS View Transitions Toggle Button Group with Morphing Thumb (Shared-Element FLIP)
  4. 04CSS Pricing Toggle with Monthly / Yearly Switch (Pure CSS, No JavaScript)
  5. 05CSS Segmented Control with Sliding Thumb Indicator (iOS-Style, Pure CSS)
  6. 06CSS Split Button Dropdown with Native <details> (Primary Action + Menu)
  7. 07CSS Icon Button Group for Toolbar Actions (Accessible Tooltips, Pure CSS)
  8. 08CSS Pill Radio Button Group with Sliding Indicator (Filter Pills, Pure CSS)
  9. 09CSS Toggle Button Group with Radio Inputs (Single-Select Alignment Group)
  10. 10CSS Wallet Connect Button Grid for Web3 Sign-In (MetaMask, WalletConnect, Coinbase)
  11. 11CSS AI Model Selector Button Group with Provider Badges (LLM Model Picker)
  12. 12CSS Segmented Control with Liquid Mercury Thumb (Metallic Stretch Animation)
  13. 13CSS Button Group with Subgrid Underline Beam (Perfectly Aligned Tab Indicator)
  14. 14CSS Multi-Select Chip Buttons with Acid Glow (Toggleable Tag Filters)
  15. 15CSS Split Button with Quantum Chevron Reveal (Animated Menu Materialize)
  16. 16CSS Format Toggle Button Group with Conic Fill (Radial Sweep Select)
  17. 17CSS Pixel Matrix Button Group with LED Segment Glow (Retro Display Buttons)
  18. 18CSS Multi-Action Button Group with Gradient Flow Progress (Animated CTA Bar)
  19. 19CSS Icon Segmented Control with Holographic Sheen (Iridescent View Switcher)
  20. 20CSS Vertical Button Stack with 3D Hover Depth (Tilting Card Buttons)
  21. 21CSS Floating Action Button with Radial Sub-Button Menu (Arc Fan-Out, Pure CSS)
  22. 22CSS Filter Button Group with RGB-Split Glitch Active State (Cyberpunk Toggle)
  23. 23CSS Pill Button Group with Rotating Conic Plasma Border (Animated Gradient Ring)
  24. 24CSS Action Button Row with Radar Shockwave Click Feedback (Ripple Pulse)
  25. 25CSS Date-Range Preset Button Group with Cursor-Following Glow (Spotlight Hover)
Pure CSSMIT licensed

CSS Pixel Matrix Button Group with LED Segment Glow (Retro Display Buttons)

A button group that looks like a retro LED dot-matrix panel — each button is a grid of tiny pixels that light up amber/green when active, complete with segment glow and a dark board bezel. The nostalgic-yet-modern 'CSS pixel matrix LED button group' for playful dashboards, retro UIs and hardware-style controls.

Live Demo
Plain CSSTailwind v4
Try it

Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS

ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link

10% off at checkout with code
Check ZTM Course

The code

<section class="btn-17" aria-label="Pixel matrix LED button group demo">
  <div class="btn-17__board">
    <p class="btn-17__label">Transport</p>
    <div class="btn-17__keys" role="radiogroup" aria-label="Transport mode">
      <input type="radio" name="btn-17" id="btn-17-1" class="btn-17__in" checked>
      <label for="btn-17-1" class="btn-17__key btn-17__key--go" aria-label="Run"><span>RUN</span></label>
      <input type="radio" name="btn-17" id="btn-17-2" class="btn-17__in">
      <label for="btn-17-2" class="btn-17__key btn-17__key--wait" aria-label="Pause"><span>WAIT</span></label>
      <input type="radio" name="btn-17" id="btn-17-3" class="btn-17__in">
      <label for="btn-17-3" class="btn-17__key btn-17__key--stop" aria-label="Stop"><span>STOP</span></label>
    </div>
  </div>
</section>
.btn-17,
.btn-17 *,
.btn-17 *::before,
.btn-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.btn-17 {
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(120% 120% at 50% 0%,#161616,#050505);
  padding: 44px 20px;
}

.btn-17__board {
  width: min(520px,100%);
  background: linear-gradient(180deg,#1c1c1c,#0e0e0e);
  border: 1px solid #2c2c2c;
  border-radius: 20px;
  padding: 24px;
  box-shadow: inset 0 2px 10px rgba(0,0,0,.8),0 30px 70px -40px #000;
}

.btn-17__label {
  font-family: ui-monospace,Menlo,monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .24em;
  color: #5a5a5a;
  margin: 0 0 14px 2px;
}

.btn-17__keys {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: 12px;
}

.btn-17__in {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.btn-17__key {
  --led: rgba(120,120,120,.22);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80px;
  border-radius: 12px;
  background: #0a0a0a;
  border: 1.5px solid #262626;
  cursor: pointer;
  overflow: hidden;
  box-shadow: inset 0 2px 6px rgba(0,0,0,.7);
}

.btn-17__key::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle,var(--led) 30%,transparent 34%) 0 0/7px 7px;
  transition: background .25s,filter .25s;
}

.btn-17__key span {
  position: relative;
  z-index: 1;
  font-family: ui-monospace,Menlo,monospace;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--led);
  text-shadow: none;
  transition: color .25s,text-shadow .25s;
}

.btn-17__key--go.btn-17__key {
}

.btn-17__in:checked + .btn-17__key--go {
  --led: #3dff6e;
  border-color: #1c7a3a;
}

.btn-17__in:checked + .btn-17__key--wait {
  --led: #ffb000;
  border-color: #8a6000;
}

.btn-17__in:checked + .btn-17__key--stop {
  --led: #ff4242;
  border-color: #8a2020;
}

.btn-17__in:checked + .btn-17__key::before {
  filter: drop-shadow(0 0 5px var(--led));
}

.btn-17__in:checked + .btn-17__key span {
  color: #fff;
  text-shadow: 0 0 8px var(--led),0 0 16px var(--led);
}

.btn-17__in:checked + .btn-17__key {
  box-shadow: inset 0 2px 6px rgba(0,0,0,.7),0 0 22px -6px var(--led);
}

.btn-17__key::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(0deg,rgba(255,255,255,.04) 0 1px,transparent 1px 3px);
  pointer-events: none;
}

.btn-17__in:focus-visible + .btn-17__key {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .btn-17__key::before,
    .btn-17__key span {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Button Group from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Pixel Matrix Button Group with LED Segment Glow (Retro Display Buttons)
Source: https://codefronts.com/components/css-button-groups/pixel-matrix/

A button group that looks like a retro LED dot-matrix panel — each button is a grid of tiny pixels that light up amber/green when active, complete with segment glow and a dark board bezel. The nostalgic-yet-modern 'CSS pixel matrix LED button group' for playful dashboards, retro UIs and hardware-style controls.
## HTML
```html
<section class="btn-17" aria-label="Pixel matrix LED button group demo">
  <div class="btn-17__board">
    <p class="btn-17__label">Transport</p>
    <div class="btn-17__keys" role="radiogroup" aria-label="Transport mode">
      <input type="radio" name="btn-17" id="btn-17-1" class="btn-17__in" checked>
      <label for="btn-17-1" class="btn-17__key btn-17__key--go" aria-label="Run"><span>RUN</span></label>
      <input type="radio" name="btn-17" id="btn-17-2" class="btn-17__in">
      <label for="btn-17-2" class="btn-17__key btn-17__key--wait" aria-label="Pause"><span>WAIT</span></label>
      <input type="radio" name="btn-17" id="btn-17-3" class="btn-17__in">
      <label for="btn-17-3" class="btn-17__key btn-17__key--stop" aria-label="Stop"><span>STOP</span></label>
    </div>
  </div>
</section>
```
## CSS
```css
.btn-17,
.btn-17 *,
.btn-17 *::before,
.btn-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.btn-17 {
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(120% 120% at 50% 0%,#161616,#050505);
  padding: 44px 20px;
}

.btn-17__board {
  width: min(520px,100%);
  background: linear-gradient(180deg,#1c1c1c,#0e0e0e);
  border: 1px solid #2c2c2c;
  border-radius: 20px;
  padding: 24px;
  box-shadow: inset 0 2px 10px rgba(0,0,0,.8),0 30px 70px -40px #000;
}

.btn-17__label {
  font-family: ui-monospace,Menlo,monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .24em;
  color: #5a5a5a;
  margin: 0 0 14px 2px;
}

.btn-17__keys {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: 12px;
}

.btn-17__in {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.btn-17__key {
  --led: rgba(120,120,120,.22);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80px;
  border-radius: 12px;
  background: #0a0a0a;
  border: 1.5px solid #262626;
  cursor: pointer;
  overflow: hidden;
  box-shadow: inset 0 2px 6px rgba(0,0,0,.7);
}

.btn-17__key::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle,var(--led) 30%,transparent 34%) 0 0/7px 7px;
  transition: background .25s,filter .25s;
}

.btn-17__key span {
  position: relative;
  z-index: 1;
  font-family: ui-monospace,Menlo,monospace;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--led);
  text-shadow: none;
  transition: color .25s,text-shadow .25s;
}

.btn-17__key--go.btn-17__key {
}

.btn-17__in:checked + .btn-17__key--go {
  --led: #3dff6e;
  border-color: #1c7a3a;
}

.btn-17__in:checked + .btn-17__key--wait {
  --led: #ffb000;
  border-color: #8a6000;
}

.btn-17__in:checked + .btn-17__key--stop {
  --led: #ff4242;
  border-color: #8a2020;
}

.btn-17__in:checked + .btn-17__key::before {
  filter: drop-shadow(0 0 5px var(--led));
}

.btn-17__in:checked + .btn-17__key span {
  color: #fff;
  text-shadow: 0 0 8px var(--led),0 0 16px var(--led);
}

.btn-17__in:checked + .btn-17__key {
  box-shadow: inset 0 2px 6px rgba(0,0,0,.7),0 0 22px -6px var(--led);
}

.btn-17__key::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(0deg,rgba(255,255,255,.04) 0 1px,transparent 1px 3px);
  pointer-events: none;
}

.btn-17__in:focus-visible + .btn-17__key {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .btn-17__key::before,
    .btn-17__key span {
    transition: none;
  }
}
```

How this works

The board is a dark bezel; each button carries a dotted pixel grid painted with a repeating radial-gradient background — a lattice of tiny unlit LEDs. When a button is :checked, the same lattice switches to a lit color and gains a layered box-shadow plus drop-shadow bloom, so the whole matrix appears to power on.

The unlit dots are a low-alpha color; lit dots are full-chroma with a glow, mimicking real LED falloff. A faint scanline overlay and inset bezel shadow sell the hardware look. Real radios keep it a single-select mode switch (Run / Pause / Stop style), fully keyboard-operable.

background:radial-gradient(circle,var(--led) 32%,transparent 34%) 0 0/7px 7px;
.in:checked + .key{ --led:#ffb000; filter:drop-shadow(0 0 6px #ffb000) }

Techniques used: repeating radial-gradient LED lattice · lit/unlit color swap on :checked · box-shadow + drop-shadow segment bloom · scanline overlay + inset bezel · single-select radios · reduced-motion safe (no animation dependency)

Make it yours

  • LED color per state via --led — amber, green, red for different modes.
  • Pixel density = the radial-gradient tile size (7px here).
  • Bezel darkness and inset shadow tune the hardware feel.
  • Add a lit "power" dot indicator per key for extra realism.

Gotchas — read before shipping

  • Dot-matrix text can be hard to read — pair the pixel look with a clear aria-label per key.
  • Don't rely on glow alone for state; the lit-vs-unlit color contrast must be strong.
  • Keep dot tiles small enough to read as pixels but not so small they moiré on low-DPI screens.
  • Radios for a single active mode; use checkboxes only if multiple LEDs can be on at once.

Browser support

ChromeSafariFirefoxEdge
allallallall

Repeating radial-gradients, box-shadow and drop-shadow are universal. No experimental features required.

Techniques used in this demo

Search CodeFronts

Loading…