AnimationUpdated in v15

Border Glow

A card whose border glows where the pointer is.

Installation

Import the class, and @use the entry point in your global styles: without it the component renders unstyled.

import { Component } from '@angular/core';
import { WrBorderGlow } from 'ngwr/bits/border-glow';

@Component({ imports: [WrBorderGlow] })
export class MyComponent {}
Angular adaptation of an effect by David Haz / reactbits.dev.

Playground

Hover me

The border lights up where the cursor is.

<wr-border-glow
  [borderRadius]="28"
  [glowRadius]="40"
  [coneSpread]="25"
  [glowIntensity]="1"
  [animated]="false"
  [loop]="false"
>
  …
</wr-border-glow>

Customize

Border Radius (px)
28 px
Glow Radius (px)
40 px
Cone Spread (%)
25 %
Glow Intensity
1.0
Animated
Loop
Speed (s)
6.0 s
Glow Color

API

NameDescriptionTypeDefault
backgroundColorCard fill. Unset, it uses the theme surface.string | nullnull
borderRadiusCorner radius in pixels.number28
glowRadiusHow far the glow reaches past the edge, in px.number40
glowIntensityGlow opacity multiplier. Does nothing without a glowColor.number1
coneSpreadWidth of the lit part, as a % of the perimeter.number25
edgeSensitivityHow fast the glow fades away from the edge. Lower is wider.number30
fillOpacityStrength of the inner fill near the edges, 0..1.number0.5
glowColorGlow colour: any CSS colour, or "H S L" parts. Unset, it follows the theme.string | nullnull
colorsGradient colours of the lit border. Unset, they follow the theme.readonly string[] | nullnull
animatedSweep the border once on mount.booleanfalse
loopCircle the border for ever, edge lit. Replaces animated; still under reduced motion.booleanfalse
speedSeconds per lap while loop is on.number6

CSS variables

Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/bits/border-glow's own element.

VariableDefaultDeclared on
--wr-border-glow-angle45deg.wr-border-glow
--wr-border-glow-colorlight-dark(hsl(40deg 90% 45% / 100%), hsl(40deg 80% 80% / 100%)).wr-border-glow
--wr-border-glow-color-10light-dark(hsl(40deg 90% 45% / 10%), hsl(40deg 80% 80% / 10%)).wr-border-glow
--wr-border-glow-color-20light-dark(hsl(40deg 90% 45% / 20%), hsl(40deg 80% 80% / 20%)).wr-border-glow
--wr-border-glow-color-30light-dark(hsl(40deg 90% 45% / 30%), hsl(40deg 80% 80% / 30%)).wr-border-glow
--wr-border-glow-color-40light-dark(hsl(40deg 90% 45% / 40%), hsl(40deg 80% 80% / 40%)).wr-border-glow
--wr-border-glow-color-50light-dark(hsl(40deg 90% 45% / 50%), hsl(40deg 80% 80% / 50%)).wr-border-glow
--wr-border-glow-color-60light-dark(hsl(40deg 90% 45% / 60%), hsl(40deg 80% 80% / 60%)).wr-border-glow
--wr-border-glow-color-sensitivitycalc(var(--wr-border-glow-edge-sensitivity) + 20).wr-border-glow
--wr-border-glow-cone-spread25.wr-border-glow
--wr-border-glow-edge-proximity0.wr-border-glow
--wr-border-glow-edge-sensitivity30.wr-border-glow
--wr-border-glow-edge-shadowinset 0 0 0 1px var(--wr-border-glow-color), inset 0 0 1px 0 light-dark(transparent, var(--wr-border-glow-color-60)), inset 0 0 3px 0 light-dark(transparent, var(--wr-border-glow-color-50)), inset 0 0 6px 0 light-dark(transparent, var(--wr-border-glow-color-40)), inset 0 0 15px 0 light-dark(transparent, var(--wr-border-glow-color-30)), inset 0 0 25px 2px light-dark(transparent, var(--wr-border-glow-color-20)), inset 0 0 50px 2px light-dark(transparent, var(--wr-border-glow-color-10)), 0 0 1px 0 var(--wr-border-glow-color-60), 0 0 3px 0 var(--wr-border-glow-color-50), 0 0 6px 0 var(--wr-border-glow-color-40), 0 0 15px 0 var(--wr-border-glow-color-30), 0 0 25px 2px var(--wr-border-glow-color-20), 0 0 50px 2px var(--wr-border-glow-color-10).wr-border-glow
--wr-border-glow-fill-blendnormal.wr-border-glow
--wr-border-glow-fill-scale0.25.wr-border-glow
--wr-border-glow-gradient-baselinear-gradient(light-dark(hsl(262deg 70% 50%), #c299ff) 0 100%).wr-border-glow
--wr-border-glow-gradient-fiveradial-gradient(at 86% 85%, light-dark(hsl(186deg 90% 38%), hsl(186deg 100% 74%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-fourradial-gradient(at 41% 38%, light-dark(hsl(192deg 90% 40%), hsl(192deg 100% 64%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-oneradial-gradient(at 80% 55%, light-dark(hsl(268deg 80% 50%), hsl(268deg 100% 76%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-sevenradial-gradient(at 51% 4%, light-dark(hsl(12deg 90% 50%), hsl(12deg 100% 72%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-sixradial-gradient(at 82% 18%, light-dark(hsl(40deg 95% 45%), hsl(52deg 100% 65%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-threeradial-gradient(at 8% 6%, light-dark(hsl(136deg 70% 38%), hsl(136deg 100% 78%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-gradient-tworadial-gradient(at 69% 34%, light-dark(hsl(349deg 85% 52%), hsl(349deg 100% 74%)) 0px, transparent 50%).wr-border-glow
--wr-border-glow-halo-blendnormal.wr-border-glow
--wr-border-glow-outlinelight-dark(var(--wr-border-base), rgb(255 255 255 / 15%)).wr-border-glow
--wr-border-glow-padding40px.wr-border-glow
--wr-border-glow-radius28px.wr-border-glow

See also