15 CSS Glowing Border Buttons

15 copy-paste CSS glowing border buttons — a rotating conic-gradient ring, a hover-triggered neon pulse, an animated border trace that laps the perimeter via mask-composite, a cyberpunk clipped-corner glow drawn with drop-shadow(), a dark-mode form input with :user-valid / :user-invalid state colors, a Tailwind-style blur glow recipe, a frosted glassmorphism border, a minimalist e-commerce outer glow, a breathing pulse urgency CTA, an inner-glow pressed toggle with aria-pressed, a subtle dark-theme glow, an SVG stroke-trace, a synthwave dual neon, a hue-shifting gradient border with @property, and a WCAG-ready accessible focus glow with a real :focus-visible outline. Scoped under .gbb-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

14 pure CSS1 light JSPublished

Related51 CSS Buttons20 CSS Animated Buttons36 CSS Button Hover Effects

Rotating Rainbow Gradient Glowing Border Button — preview
01 / 15Pure CSS

Rotating Rainbow Gradient Glowing Border Button

The definitive dark-theme SaaS primary CTA: a full-spectrum conic-gradient ring orbits the button forever, with a blurred twin of the same gradient breathing underneath as the glow. Built on @property so the rotation is a real, hardware-cheap CSS animation — zero JavaScript, zero libraries.

Published

Neon Pulse Glow Button on Hover — preview
02 / 15Pure CSS

Neon Pulse Glow Button on Hover

The esports lobby classic: a cyan sign-tube button that snaps to full neon on hover — four stacked box-shadow layers, a matching text-shadow, and a heartbeat pulse that keeps throbbing while the cursor stays. Reads exactly like a bent-glass sign because the shadow layers mimic how real neon light falls off.

Published

Pure CSS Animated Border Trace Button — preview
03 / 15Pure CSS

Pure CSS Animated Border Trace Button

A single comet of light sweeps the button's perimeter on hover — no SVG, no JavaScript. A rotating conic-gradient wedge is clipped to a 2px border ring with the mask-composite trick, so the beam hugs any border-radius perfectly. The go-to 'expensive detail' for portfolio and dev-tool sites.

Published

Cyberpunk Sci-Fi Glowing Corner Border Button — preview
04 / 15Pure CSS

Cyberpunk Sci-Fi Glowing Corner Border Button

Angular Web3/HUD energy: a clip-path button with sliced corners, amber corner brackets, and a glow that follows the clipped shape exactly — because it uses drop-shadow(), not box-shadow. On hover the brackets snap outward and a scanline flickers across the face.

Published

Dark Mode Glowing Input & Submit Focus States — preview
05 / 15Pure CSS

Dark Mode Glowing Input & Submit Focus States

A checkout-grade mini form where the glow is UX, not decoration: the email field breathes a violet halo on focus, flips to a green glow once the address is valid and red only after you've actually typed something wrong — via :user-valid/:user-invalid — and the submit button answers with its own glow on hover and focus.

Published

Tailwind CSS Glowing Gradient Border Button (Recipe) — preview
06 / 15Pure CSS

Tailwind CSS Glowing Gradient Border Button (Recipe)

The exact glowing-border pattern that ships in modern React/Next.js apps — an absolutely-positioned gradient layer, nudged out with -inset-0.5, blurred, and revealed on group-hover — implemented here in plain CSS line-for-line, with the equivalent Tailwind utility string documented so you can paste either version.

Published

Glassmorphism Button with Subtle Glow Border — preview
07 / 15Pure CSS

Glassmorphism Button with Subtle Glow Border

Fintech-dashboard glass: a backdrop-blurred button whose hairline border is a real gradient (bright top-left, fading bottom-right — how light actually hits glass), with a soft interior sheen that drifts toward the cursor side on hover. Quiet at rest, unmistakably premium in motion.

Published

Minimalist Outer Glow Box-Shadow Button — preview
08 / 15Pure CSS

Minimalist Outer Glow Box-Shadow Button

The restrained e-commerce workhorse: a solid brand-colored Add to Cart whose glow is a single soft box-shadow in the button's own color, swelling gently on hover with a 2px lift. No gradients, no animation loops — just the shadow discipline that makes conversion buttons feel pressable on light themes.

Published

Multi-Layer Breathing Glow Pulse Button — preview
09 / 15Pure CSS

Multi-Layer Breathing Glow Pulse Button

The attention magnet for live demos and expiring offers: with no interaction at all, a sonar ring expands and dissolves from the button's edge every 2.2 seconds while the border glow breathes underneath on an offset rhythm. Two desynchronized loops read as 'alive', not 'blinking'.

Published

Inner Glow Border Toggle Button (Pressed State) — preview
10 / 15CSS + JS

Inner Glow Border Toggle Button (Pressed State)

A media-player toggle where the light physically relocates: off, the glow rings the outside of the border; press it, and the same light collapses inward as an inset flare — the button looks lit from within while playing. Five lines of JS manage aria-pressed; CSS does all the optics.

Published

Subtle Soft Glow Dark Theme Button — preview
11 / 15Pure CSS

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

SVG Animated Path Glowing Stroke Button — preview
12 / 15Pure CSS

SVG Animated Path Glowing Stroke Button

The agency-showcase flex: on hover, a glowing stroke draws itself around the button's rounded outline from a single origin point, meets itself, and holds — powered by stroke-dasharray on an SVG rect with pathLength="100", so the dash math is percentage-simple regardless of the button's real size.

Published

Retro 80s Synthwave Dual Neon Glowing Button — preview
13 / 15Pure CSS

Retro 80s Synthwave Dual Neon Glowing Button

Miami 1986: magenta and cyan tube-borders offset like misregistered chrome print, italic wide-tracked type with a sunset gradient fill, and a startup flicker that stutters the sign to life on hover — all against a perspective laser-grid floor drawn in two repeating-linear-gradients.

Published

Smooth Gradient Hue-Shift Border Button — preview
14 / 15Pure CSS

Smooth Gradient Hue-Shift Border Button

The 'Most Popular' plan highlighter: the button's border and halo drift continuously through the color wheel — violet to cyan to rose and back — by animating a single registered hue number through oklch(). Because only hue moves (lightness and chroma pinned), every frame is equally vivid and the label never loses contrast.

Published

Accessible Glowing Focus State Button (WCAG-Ready) — preview
15 / 15Pure CSS

Accessible Glowing Focus State Button (WCAG-Ready)

The enterprise closer: a glowing focus treatment engineered to WCAG 2.2 — a 3px offset outline PLUS a soft glow that appears only for keyboard navigation via :focus-visible, stays ≥3:1 against every adjacent color, and swaps itself for system colors under forced-colors mode. Tab into the demo to see it fire.

Published

FAQ

Frequently asked questions

What actually makes a CSS glowing border button glow — box-shadow, drop-shadow, or a mask ring?
There are four techniques doing real work across the 15 demos, and picking the wrong one is the difference between a button that ships and one that jitters on mid-range hardware. The first and most common is stacked box-shadow halos, which is what Demo 02 (Neon Pulse) leans on — a tight 0 0 8px inner ring plus a 0 0 24px outer bloom, both in the accent color, both animated via a keyframe that scales the blur radius. box-shadow is composited on the GPU, doesn't force layout, and respects border-radius, which is why it stays the workhorse for neon and pulse effects. The second is filter: drop-shadow(), used in Demo 04 (Cyberpunk Clipped-Corner). Unlike box-shadow, drop-shadow follows the actual painted shape — including anything cut by clip-path — which is the only way to get a real glow around a hexagonal or bracketed HUD button. The tradeoff is cost: filter triggers an offscreen buffer, so use it on a wrapper element, not on a hover-repeating keyframe. The third is a mask-composite ring, the technique in Demo 03 (Comet Border Trace). You paint a conic-gradient on a ::before, then use a two-layer mask with mask-composite: exclude to punch out the interior — leaving just a 1-2px ring that the gradient rotates through. The fourth is @property-driven conic-gradient rotation, the technique in Demo 01 (Rotating Rainbow Ring). Without @property registering the angle as an <angle> type, the browser interpolates it as a string and snaps rather than tweening. For picking between them: use box-shadow for soft halos, drop-shadow when clip-path is involved, mask-composite for hairline animated borders, and @property + conic for anything that needs to rotate continuously.
How do I make a rotating gradient border button in pure CSS with @property?
Demo 01 is the reference. The pattern has three moving parts and one of them is non-obvious. First, register a custom property as an <angle>: @property --angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; }. Second, paint the border ring on a ::before pseudo-element positioned inset: -2px behind the button, filled with background: conic-gradient(from var(--angle), #ff006e, #8338ec, #3a86ff, #ff006e) — the repeated first color is what closes the loop cleanly. Third, animate the angle: @keyframes spin { to { --angle: 360deg; } } plus animation: spin 4s linear infinite. The gotcha every developer hits: without @property, the CSS parses fine, DevTools shows the keyframe running, and nothing rotates. This is because unregistered custom properties are treated as * (any string) by the interpolation engine — 0deg to 360deg gets discretely swapped, not tweened, so the ring appears frozen. @property types the variable so the browser knows to interpolate it numerically. Browser support matters: @property shipped in Chromium 85+, Safari 16.4+, Firefox 128+. For older Firefox, you can fall back to a static gradient by putting the animation inside @supports (background: paint(something)) or simply accepting the static ring — it still reads as a glowing border. To layer this with a solid button interior, give the actual <button> a background matching your surface color and use z-index to stack it over the ::before. For the reduced-motion path, wrap the animation in @media (prefers-reduced-motion: no-preference) so the ring stays visible but stationary.
How do I animate a comet or border trace effect around a button on hover?
Demo 03 is the reference, and the trick is a two-layer mask that most tutorials get wrong. The setup: a ::before pseudo-element sits inset: 0 over the button, painted with a conic-gradient(from var(--angle), transparent 0deg, transparent 300deg, #00ffcc 340deg, transparent 360deg). That gives you a short bright arc in an otherwise transparent circle — the comet's tail. On its own, this fills the entire button surface. To turn it into just a ring, you apply two mask layers: mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0) with mask-composite: exclude. The first mask covers the interior via content-box; the second covers everything; XOR-ing them leaves only the padding-box ring visible. Set padding: 2px on the pseudo to control ring thickness. The -webkit-mask-composite quirk: Safari's prefixed syntax uses different keywords. Ship both: -webkit-mask-composite: xor; mask-composite: exclude; — those two produce the same visual result across engines but the keywords are not interchangeable. Animate the angle with the same @property pattern from Demo 01 so the comet loops around. For the hover-only variant, put the animation behind button:hover::before { animation: trace 2s linear infinite; } and give the base state opacity: 0 with a short transition so the ring fades in when the cursor arrives. One accessibility note: pair the trace with a color change or shadow on :focus-visible — keyboard users don't hover, so a hover-only trace leaves them without any focus affordance.
How do I build a neon glow button that's actually accessible for keyboard users?
Demo 15 is the accessibility exemplar and codifies the four rules that separate a shippable glow button from a lawsuit. Rule one: WCAG 2.4.13 (Focus Appearance) requires a focus indicator that's either a minimum 2px thick outline or has 3:1 contrast against adjacent colors. A soft 40px bloom shadow does not satisfy this on its own — glow spreads outward and often washes out against light backgrounds. Pair the glow with a solid outline: 2px solid var(--focus) or an equivalent box-shadow: 0 0 0 2px var(--focus) ring. Rule two: use :focus-visible, not :focus. :focus fires on mouse clicks too, which is why designers historically stripped it and broke keyboard nav. :focus-visible only fires when the browser's heuristic decides focus should be shown — keyboard tabs, screen reader nav — so you can style it aggressively without lighting up on click. Rule three: never gate the glow on :hover alone. Keyboard users don't hover. Every hover-triggered visual should also be triggered by :focus-visible: button:hover, button:focus-visible { box-shadow: 0 0 24px var(--glow); }. Rule four: support forced-colors (Windows High Contrast Mode). Inside @media (forced-colors: active), replace glow colors with system tokens: outline: 2px solid CanvasText; box-shadow: none;. The forced-colors engine strips box-shadow and custom colors anyway, so if glow is your only affordance, high-contrast users see nothing. Also honor prefers-reduced-motion — replace any pulsing keyframe with a static glow at the same intensity.
How do I ship a SaaS pricing page CTA with a breathing glow (Stripe, Vercel, Linear, Notion style)?
Demo 09 is the reference and it maps directly to the pattern shipped on Stripe.com/pricing, Linear.app/pricing, Vercel.com/pricing, and Notion.so/pricing. The visual grammar is consistent across all four: a solid primary-color button on the recommended tier, with a subtle bloom that pulses roughly once every 2-3 seconds — slow enough to read as breathing, not blinking. The CSS is a two-keyframe animation on box-shadow: @keyframes breathe { 0%, 100% { box-shadow: 0 0 20px rgba(99, 102, 241, 0.4); } 50% { box-shadow: 0 0 40px rgba(99, 102, 241, 0.7); } } applied as animation: breathe 3s ease-in-out infinite. Now the real gotcha, which is why this FAQ exists. On hover, you want the button to snap to a stronger static glow — a reward state. Every developer's first instinct is button:hover { animation-play-state: paused; }. This fails silently. A paused animation still owns the box-shadow property — it's frozen at whatever keyframe frame the pause caught, and any box-shadow you set in :hover is overridden by the animation's computed value. The fix: button:hover { animation: none; box-shadow: 0 0 48px rgba(99, 102, 241, 0.9); }. Setting animation: none fully removes the declaration from the cascade, freeing box-shadow for the hover rule to write. This is a real, tested pattern — every SaaS pricing team hits it. The other pattern detail: only apply breathing to ONE button per pricing card grid. Multiple pulsing CTAs read as chaos and undermine the visual hierarchy that says 'pick this tier'. Also honor prefers-reduced-motion by replacing the animation with a static strong glow — vestibular-sensitive users still see the affordance, just not the pulse. For the copy on the button, keep it verb-first (Start free trial, Get started, Upgrade to Pro) — the glow does the attention work, so the text can be direct.
How do I build a dark-mode form input glow for a fintech signup (Stripe Checkout, Linear signup style)?
Demo 05 is the reference and it uses the two selectors that separate modern fintech input UX from 2015-era validation: :user-valid and :user-invalid. Old-school :valid and :invalid match from page load — meaning an empty required field is red before the user has typed a single character. Every user hates this. :user-valid and :user-invalid only match AFTER the user has interacted with the field and blurred or submitted, which is the actual UX contract every serious signup form wants. This is what Stripe Elements, Plaid Link, and Linear's signup flow ship. The CSS pattern for the input itself: neutral box-shadow: 0 0 0 1px var(--border) at rest, box-shadow: 0 0 0 2px var(--accent), 0 0 12px color-mix(in oklch, var(--accent) 40%, transparent) on :focus-visible. On :user-valid, swap the accent for a green token; on :user-invalid, swap for red. Using color-mix() for the glow layer means you define one accent color and derive the transparent bloom from it — no separate glow variable to maintain. The caret-color: var(--accent) declaration matches the blinking cursor to the state color, which is the polish detail that reads as built by someone who cares. The accessibility non-negotiable: never remove outline without replacing it with a box-shadow ring at 3:1 contrast against the input background. Screen reader users navigating with keyboard need to know which field has focus — a color-only cue fails colorblind users too, so the ring thickness itself is the affordance. For the submit button, tie its enabled state to form:has(:user-invalid) button[type='submit'] { opacity: 0.5; pointer-events: none; } — modern :has() support means you can gate submission on form validity without a single line of JavaScript.
How do I build a cyberpunk / Web3 / gaming CTA button with clipped-corner glow?
Demo 04 is the reference and it's the pattern OpenSea, Rarible, and most Web3/NFT marketplaces ship for connect-wallet and mint CTAs. The sci-fi shape comes from clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px) — a rectangle with two corners cut, giving that HUD/lock-on silhouette. The critical gotcha: clip-path clips everything painted on the element, including box-shadow. If you put the glow on the same element as the clip-path, the glow gets cut off at the polygon edge and you see nothing outside the shape. The fix: wrap the button in a container div, apply clip-path to the button, and apply filter: drop-shadow(0 0 16px #00ffcc) to the WRAPPER. drop-shadow follows the clipped shape's actual painted geometry, so the cyan bloom hugs the hex outline instead of a rectangular bounding box. The corner-bracket HUD detail — those small L-shaped marks in the corners — comes from two absolutely-positioned pseudo-elements: ::before in the top-left with border: 2px 0 0 2px solid #00ffcc; width: 12px; height: 12px; and ::after mirrored in the bottom-right. That's what sells the targeting reticle aesthetic that gaming and Web3 audiences read as native. On hover, animate the bracket size outward with a transform: scale(1.15) plus a stronger drop-shadow — the brackets read as tracking to the click. Color-wise, stick to the cyan/magenta/lime palette that dominates crypto UI — #00ffcc, #ff00aa, #c3ff00 — because those are the exact tokens users associate with on-chain action. For accessibility, pair the visual with :focus-visible { outline: 2px solid currentColor; outline-offset: 4px; } so keyboard users get a real ring even inside the clipped shape.
How do I add a Tailwind CSS glowing gradient border to a button?
Demo 06 is the reference and it codifies the canonical Tailwind blur-underneath recipe — the pattern shipped across Vercel, Linear, and most modern Next.js marketing sites. The trick is not a border at all: it's an absolutely-positioned blurred gradient div sitting BEHIND the button, scaled up slightly on hover to bloom out from under the button edges. Vanilla CSS version: give the button position: relative and add a ::before with content: ''; position: absolute; inset: -2px; background: linear-gradient(90deg, #ff006e, #8338ec, #3a86ff); filter: blur(12px); opacity: 0.6; z-index: -1; transition: opacity 0.3s, transform 0.3s; then on hover opacity: 1; transform: scale(1.1);. The Tailwind class equivalent: wrap the button in a <div class='relative group'> and add a sibling <div class='absolute -inset-0.5 bg-gradient-to-r from-pink-500 via-purple-500 to-blue-500 rounded-lg blur opacity-60 group-hover:opacity-100 group-hover:scale-110 transition duration-300'></div> before the actual button. The group and group-hover: primitives are how Tailwind wires parent-triggered child states without extra JS. Why blur-underneath instead of a real border image: gradient borders in CSS are historically painful — border-image with gradients doesn't respect border-radius in most engines. Blurring a shape behind the button sidesteps the whole problem and produces the softer, more expensive-looking glow that ships on production SaaS sites. This pattern works identically in Next.js (App Router or Pages), Astro (both static and island hydration), SvelteKit, Nuxt, and Remix — nothing about it is framework-specific, because it's just two divs and a hover state. For the color palette, sample from your brand's existing gradient tokens rather than defaulting to purple-pink — the effect looks generic if every button uses the Tailwind rainbow.
Do these glowing button demos work with React, Next.js, Vue, Svelte, Astro, and Tailwind?
Yes — all 15 demos are framework-agnostic. Every demo is real semantic HTML (real <button type='button'>, real <a href>, real <input>) plus scoped CSS under a .gbb-NN class prefix, plus (in exactly one case, Demo 10's aria-pressed toggle) a small vanilla JS listener. Porting is mechanical. For React and Next.js: the HTML pastes into JSX with the usual attribute renames — class becomes className, inline styles become objects, for becomes htmlFor. Keep type='button' on every non-submit button so React doesn't accidentally submit an ancestor form. Drop the CSS into a CSS Module, a <style jsx> block, or a global stylesheet — the .gbb-NN scoping means it won't leak. For Demo 10's toggle JS, wrap it in a useEffect(() => { ... }, []) so the listener attaches after mount and gets torn down on unmount. For Vue 3 (Composition or Options): HTML goes straight into the template unchanged, CSS into a <style scoped> block, JS into onMounted(). For Svelte and SvelteKit: HTML unchanged, CSS in the component's <style> block (already scoped by default), JS in onMount(). For Astro: HTML into an .astro file exactly as-is, CSS in the frontmatter <style> block (scoped by default), JS in a <script> tag (deferred by default, which is what you want). For Tailwind users who want to convert: the pure-CSS versions are provided as the ground truth so you can translate class-by-class, and Demo 06 is already written with the Tailwind blur-underneath pattern as its explicit source. The one universal note: 14 of the 15 demos are pure CSS with zero runtime cost — no hydration, no reactivity, no event listeners. They render server-side in Next.js and Astro static output identically to how they render in the browser. Only Demo 10 needs the JS boundary, and its handler is 8 lines.

Related collections

15 CSS 3D Tilt Hover Cards preview

15 CSS 3D Tilt Hover Cards

15 mouse-aware 3D tilt hover cards — e-commerce product spotlight, glassmorphism parallax team card, interactive pricing tier, holographic NFT collectible, pop-out mascot, dark tech grid with border glow, media player album art, blog article preview, cyberpunk neon glow, dashboard KPI widget, minimalist real estate, flip-to-back tilt, mobile app showcase, course learning card, and a Pure CSS touch-friendly tilt. Vanilla JS writes --rx/--ry/--mx/--my; all rendering stays in CSS on the GPU.

24 CSS Animated Cards preview

24 CSS Animated Cards

24 hand-coded CSS animated card patterns organised by what triggers the motion, not by card style. Scroll and entrance triggers: staggered grid reveals, @starting-style mount-in, scroll-driven scale and fade on animation-timeline: view(), View Transitions API card-to-detail morphs, blur-to-sharp lazy image loading, and FLIP re-layout when a filter changes. State-change triggers: add-to-cart success morph, like and save particle burst, expand and collapse to intrinsic height with calc-size(), swipe-to-dismiss on Pointer Events, and skeleton-to-loaded crossfade. Data-driven triggers: count-up KPI metrics, SVG sparkline draw-on-enter, and progress ring fill on load. Ambient idle loops: breathing glow, floating drift, animated gradient mesh backgrounds, conic rotating borders, auto-cycling testimonial decks, and live status pulses. Plus four hover patterns where the effect is the topic itself: cursor spotlight, holographic foil glare, corner ribbon slide, and horizontal accordion expand. Every card is scoped under a .ac-NN prefix for no-collision pasting, guards prefers-reduced-motion, animates compositor-only properties, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

22 CSS Avatars preview

22 CSS Avatars

22 hand-coded CSS avatars for chat apps, team dashboards, comment threads, account menus, and social profiles. Covers circular and squircle shapes, gradient and conic story rings, hexagon clip-path crops, online status dots, notification count badges, verified checkmarks, stacked facepiles with plus-N overflow, initials fallbacks for users without photos, broken-image recovery, avatar pickers, and a size scale system where the ring, badge, and status dot all scale from a single custom property.

Search CodeFronts

Loading…