import { Component } from '@angular/core';
import { WrGradientFlow } from 'ngwr/animations/gradient-flow';
@Component({ imports: [WrGradientFlow] })
export class MyComponent {}Gradient Flow
A short piece of text, a brand name or one word, filled with a gradient of theme inks that drifts slowly along it, forever, as a seamless loop. It has no inputs: the colours and the cadence are CSS variables.
Installation
Import the class, and @use the entry point in your global styles. Nothing warns you when the @use is missing.
Basic
Put wrGradientFlow on an element that shrinks to its text: an inline, an inline-block, a flex item. The gradient spans the host's box, so a block stretched wider than its word shows the word only a slice of it. The static gradient is CSS alone; the directive only sets the drift running while the text is on screen and the page is visible, and pausing keeps the phase.
<h2><span wrGradientFlow>ngtrue</span></h2>Colours
--wr-gradient-flow-from is the colour the loop starts and ends on and --wr-gradient-flow-via the stops in between, a comma-separated list. The defaults are inks: each intent as text on the surface, so every blend along the word stays readable in both schemes.
<span
wrGradientFlow
style="--wr-gradient-flow-from: var(--wr-color-danger-ink); --wr-gradient-flow-via: var(--wr-color-warning-ink)"
>Sunset</span
>Cadence
--wr-gradient-flow-cycle is one full loop, 8 s unset; a wave crosses the word in half of it. The slide is stepped, not continuous, so a frame that would move the image by less than a pixel is not repainted: --wr-gradient-flow-steps is how many steps a cycle has, 120 unset. --wr-gradient-flow-selected is the solid fill the glyphs take while selected.
.brand {
--wr-gradient-flow-cycle: 4s;
--wr-gradient-flow-steps: 60;
}Accessibility
| Part | Behaviour |
|---|---|
| Screen readers | Nothing changes: no split, no copy, no pseudo-element. The gradient is a background clipped to the glyphs, so what is announced, selected and copied is the text as authored. |
| Reduced motion | Under prefers-reduced-motion: reduce the gradient stays and nothing moves: it is colour, not motion. The demos on this page follow the same setting. |
| Forced colours | Under forced-colors: active the text is plain, in the system colour, and the directive does not run. |
| Server | The server paints the final colours before any script arrives. The drift starts in the browser, after the first render, and only where IntersectionObserver exists. |
| Direction | The wave travels the reading direction: under dir="rtl" it drifts right to left. |
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/gradient-flow declares each default on its own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-gradient-flow-cycle | 8s | .wr-gradient-flow |
--wr-gradient-flow-from | var(--wr-color-primary-ink) | .wr-gradient-flow |
--wr-gradient-flow-selected | var(--wr-color-on-surface) | .wr-gradient-flow |
--wr-gradient-flow-steps | 120 | .wr-gradient-flow |
--wr-gradient-flow-via | var(--wr-color-info-ink), var(--wr-color-success-ink) | .wr-gradient-flow |
See also
Animation ShimmerA soft band of light crosses the glyphs of a short label, waits, and crosses again for as long as the label is on screen.Animation OrbitA short label set around a circle, like a seal, turning slowly, with a slot in the middle for a mark that does not turn.Guide ColorsThe --wr-color-* tokens, and which one to use for fills, text and borders.