import { Component } from '@angular/core';
import { WrGlowBorder } from 'ngwr/animations/glow-border';
@Component({ imports: [WrGlowBorder] })
export class MyComponent {}Glow Border
A short arc of brand light runs round the host's edge for ever, with a soft glow spilling outward. CSS does all of it; the directive only decides whether the arc turns.
Installation
Import the class, and @use the entry point in your global styles. Nothing warns you when the @use is missing.
Basic
Put wrGlowBorder on a positioned element; wr-btn is one. Two pseudo-elements carry one conic gradient turned by a registered angle: the arc itself, masked down to the ring, and a wider, blurred copy under the host, so only what spills past the edge shows. The host's own hover and focus states are untouched, and its focus ring paints above the arc.
<a wr-btn outlined size="lg" routerLink="/docs" wrGlowBorder>Get started</a>The parent
The blurred copy sits at a negative z-index, so the host's stacking parent isolates itself to keep that copy above the page background. The host itself must not form a stacking context, or the copy would paint over its own fill.
.hero {
position: relative;
isolation: isolate;
}Stopping the arc
active stops the arc without removing the directive: the ring stays lit and still. The same still ring is what a reader with reduced motion sees, and what a hidden tab holds.
<button wr-btn outlined type="button" wrGlowBorder [active]="live()">Stop and start</button>Colours
--wr-glow-border-color is the arc's centre, primary by default; -warm and -cool, the two edges, are mixed from it toward danger and success, so one hook recolours the whole arc. Set it to a theme role on the host or above it: an intent for a call to action, the muted ink for a quiet ring.
<button wr-btn outlined type="button" wrGlowBorder>Primary</button>
<button wr-btn outlined type="button" wrGlowBorder style="--wr-glow-border-color: var(--wr-color-success)">Success</button>
<button wr-btn outlined type="button" wrGlowBorder style="--wr-glow-border-color: var(--wr-color-danger)">Danger</button>
<button wr-btn outlined type="button" wrGlowBorder style="--wr-glow-border-color: var(--wr-color-on-surface-muted)">Neutral</button>Ring, glow and period
--wr-glow-border-width is the ring, --wr-glow-border-blur and -strength the glow that spills past the edge, and --wr-glow-border-period one turn, 4.5 s unset.
<button wr-btn outlined type="button" wrGlowBorder style="--wr-glow-border-width: 2px; --wr-glow-border-strength: 0.9; --wr-glow-border-period: 2s">
Thicker, brighter, faster
</button>Accessibility
| Part | Behaviour |
|---|---|
| Screen readers | Nothing is added to the host: no children, no attributes a reader hears. The arc is two pseudo-elements. |
| Reduced motion | Under prefers-reduced-motion: reduce the ring stays lit and still. |
| Hidden document | The arc stops while the tab is hidden and turns again when it is visible. |
| Server | The still ring is rendered; the turn starts in the browser. |
API
| Name | Description | Type | Default |
|---|---|---|---|
active | Stops the arc without removing the directive. | boolean | true |
CSS variables
Set these on the element itself, with a rule more specific than its Declared on selector. In a global stylesheet, put a class of yours on an ancestor it really has: <body> for an overlay panel, which renders outside your markup. In a component stylesheet the selector alone works, but only for an element in that component's own template. A value on a wrapper or :root is shadowed, because ngwr/animations/glow-border declares each default on its own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-glow-border-blur | 14px | .wr-glow-border |
--wr-glow-border-color | var(--wr-color-primary) | .wr-glow-border |
--wr-glow-border-cool | color-mix(in oklch, var(--wr-glow-border-color) 70%, var(--wr-color-success)) | .wr-glow-border |
--wr-glow-border-period | 4.5s | .wr-glow-border |
--wr-glow-border-strength | 0.6 | .wr-glow-border |
--wr-glow-border-warm | color-mix(in oklch, var(--wr-glow-border-color) 70%, var(--wr-color-danger)) | .wr-glow-border |
--wr-glow-border-width | 1.5px | .wr-glow-border |