15 CSS Glowing Border Buttons11 / 15

Pure CSSMIT licensed

Subtle Soft Glow Dark Theme Button

The 'invisible craft' button for developer docs and minimalist SaaS: at rest it's a quiet outlined control; on hover the border warms by one step and a glow so faint you feel it more than see it settles around the edge. The whole effect lives inside a 12% opacity budget — restraint as a feature.

Published

Live Demo
Try it

The code

<section class="gbb-11" aria-label="Subtle soft glow dark theme buttons demo">
  <div class="gbb-11__row">
    <button class="gbb-11__btn gbb-11__btn--primary" type="button">Read the docs</button>
    <button class="gbb-11__btn" type="button">View changelog</button>
  </div>
</section>
.gbb-11,
.gbb-11 *,
.gbb-11 *::before,
.gbb-11 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.gbb-11 {
  --acc: oklch(0.72 0.09 240);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  background: oklch(0.16 0.008 260);
}

.gbb-11 .gbb-11__row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}

.gbb-11 .gbb-11__btn {
  cursor: pointer;
  border-radius: 10px;
  padding: 13px 24px;
  font: 500 14px/1 'Segoe UI',system-ui,sans-serif;
  color: rgba(255,255,255,.78);
  background: oklch(0.19 0.01 260);
  border: 1px solid color-mix(in oklab,var(--acc) 12%,rgba(255,255,255,.1));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06),0 0 24px color-mix(in oklab,var(--acc) 0%,transparent);
  transition: border-color .4s ease,box-shadow .4s ease,color .4s ease,background .4s ease;
}

.gbb-11 .gbb-11__btn:hover,
.gbb-11 .gbb-11__btn:focus-visible {
  color: #fff;
  border-color: color-mix(in oklab,var(--acc) 32%,rgba(255,255,255,.14));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08),0 0 24px color-mix(in oklab,var(--acc) 12%,transparent);
}

.gbb-11 .gbb-11__btn--primary {
  color: #fff;
  background: color-mix(in oklab,var(--acc) 14%,oklch(0.2 0.012 260));
  border-color: color-mix(in oklab,var(--acc) 28%,rgba(255,255,255,.12));
}

.gbb-11 .gbb-11__btn--primary:hover,
.gbb-11 .gbb-11__btn--primary:focus-visible {
  border-color: color-mix(in oklab,var(--acc) 55%,rgba(255,255,255,.14));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1),0 0 24px color-mix(in oklab,var(--acc) 22%,transparent);
}

.gbb-11 .gbb-11__btn:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 3px;
}

.gbb-11 .gbb-11__btn:active {
  background: oklch(0.17 0.01 260);
}

@media (prefers-reduced-motion: reduce) {
  .gbb-11 .gbb-11__btn {
    transition: none;
  }
}
/* No JavaScript — three sub-threshold changes (border step, 12% halo, label brighten) on a slow 400ms ease compound into quiet polish. */
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 Glowing Border Button 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: Subtle Soft Glow Dark Theme Button
Source: https://codefronts.com/components/css-glowing-border-buttons/subtle-soft-glow-dark-theme-button/

The 'invisible craft' button for developer docs and minimalist SaaS: at rest it's a quiet outlined control; on hover the border warms by one step and a glow so faint you feel it more than see it settles around the edge. The whole effect lives inside a 12% opacity budget — restraint as a feature.
## HTML
```html
<section class="gbb-11" aria-label="Subtle soft glow dark theme buttons demo">
  <div class="gbb-11__row">
    <button class="gbb-11__btn gbb-11__btn--primary" type="button">Read the docs</button>
    <button class="gbb-11__btn" type="button">View changelog</button>
  </div>
</section>
```
## CSS
```css
.gbb-11,
.gbb-11 *,
.gbb-11 *::before,
.gbb-11 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.gbb-11 {
  --acc: oklch(0.72 0.09 240);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  background: oklch(0.16 0.008 260);
}

.gbb-11 .gbb-11__row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}

.gbb-11 .gbb-11__btn {
  cursor: pointer;
  border-radius: 10px;
  padding: 13px 24px;
  font: 500 14px/1 'Segoe UI',system-ui,sans-serif;
  color: rgba(255,255,255,.78);
  background: oklch(0.19 0.01 260);
  border: 1px solid color-mix(in oklab,var(--acc) 12%,rgba(255,255,255,.1));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06),0 0 24px color-mix(in oklab,var(--acc) 0%,transparent);
  transition: border-color .4s ease,box-shadow .4s ease,color .4s ease,background .4s ease;
}

.gbb-11 .gbb-11__btn:hover,
.gbb-11 .gbb-11__btn:focus-visible {
  color: #fff;
  border-color: color-mix(in oklab,var(--acc) 32%,rgba(255,255,255,.14));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08),0 0 24px color-mix(in oklab,var(--acc) 12%,transparent);
}

.gbb-11 .gbb-11__btn--primary {
  color: #fff;
  background: color-mix(in oklab,var(--acc) 14%,oklch(0.2 0.012 260));
  border-color: color-mix(in oklab,var(--acc) 28%,rgba(255,255,255,.12));
}

.gbb-11 .gbb-11__btn--primary:hover,
.gbb-11 .gbb-11__btn--primary:focus-visible {
  border-color: color-mix(in oklab,var(--acc) 55%,rgba(255,255,255,.14));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1),0 0 24px color-mix(in oklab,var(--acc) 22%,transparent);
}

.gbb-11 .gbb-11__btn:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 3px;
}

.gbb-11 .gbb-11__btn:active {
  background: oklch(0.17 0.01 260);
}

@media (prefers-reduced-motion: reduce) {
  .gbb-11 .gbb-11__btn {
    transition: none;
  }
}
```

## JavaScript
```js
/* No JavaScript — three sub-threshold changes (border step, 12% halo, label brighten) on a slow 400ms ease compound into quiet polish. */
```

How this works

Three tiny moves, each barely perceptible, that compound into 'polished': (1) border-color steps from 12% to 32% white-mix of the accent; (2) a wide, very faint halo — 0 0 24px at just 12% accent — fades in; (3) the label brightens from 78% to 100% white. Every value is deliberately below the threshold where you'd consciously notice any single change; together they read as the button 'waking up'. The 400ms ease-out (slower than typical hovers) is part of the quietness — nothing snaps.

The one indulgence is a top-edge sheen: an inset 0 1px 0 rgba(255,255,255,.06) that suggests machined metal. This is the pattern for surfaces where a rotating rainbow would be vandalism — docs, settings pages, CLIs. The demo shows a primary + ghost pair because that hierarchy IS the design: the ghost gets the halo only at half strength, keeping the pecking order legible even mid-hover.

Make it yours

  • Whole personality lives in --acc — desaturated blue (shown) reads technical; sage reads calm; keep chroma under 0.12 or 'subtle' dies.
  • The 12%/24px halo is the ceiling for docs; drop to 8% for text-adjacent buttons.
  • Ghost variant: copy the second ruleset — it's the primary at half opacity everywhere.
  • Increase the transition to 600ms for reading-heavy pages where nothing should move fast.

Gotchas — read before shipping

  • Subtle ≠ inaccessible: the label still moves from 78%→100% white, and the focus ring is full-contrast — only the DECORATION is quiet.
  • Check the halo on your real page background; 12% glow disappears entirely on #000 and needs ~18% there.
  • Resist adding transform lift — motion contradicts the calm register this pattern exists for.

Browser support

ChromeSafariFirefoxEdge
111+16.2+113+111+

color-mix() only. With rgba() fallbacks this runs anywhere; the design predates the syntax.

Techniques used in this demo

Search CodeFronts

Loading…