# 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.

Source: https://ngwr.dev/animations/glow-border  
Kind: Animation, Directive, CSS  
Added in v15.7

## Installation

Import the class, and `@use` the entry point in your global styles. Nothing warns you when the `@use` is missing.

```typescript
import { Component } from '@angular/core';
import { WrGlowBorder } from 'ngwr/animations/glow-border';

@Component({ imports: [WrGlowBorder] })
export class MyComponent {}
```

```scss
@use 'ngwr/animations/glow-border';
```

## 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.

```angular-html
<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.

```scss
.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.

```angular-html
<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.

```angular-html
<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.

```angular-html
<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` |

## See also

- [Shimmer](https://ngwr.dev/animations/shimmer) — A soft band of light crosses the glyphs of a short label, waits, and crosses again for as long as the label is on screen.
- [Button](https://ngwr.dev/reference/components/button) — A button for an action or a link.
- [Motion](https://ngwr.dev/guides/tokens/motion) — Easing and duration tokens for your transitions and animations.
- [Switch](https://ngwr.dev/reference/components/switch) — Turn a setting on or off.
