Skip to content

corysimmons/react-gradient-borders

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-gradient-borders

react-gradient-borders

Animated gradient borders for React components using SVG-based path-following gradients.

Installation

npm install react-gradient-borders

Usage

import { GradientBorder } from 'react-gradient-borders';

function App() {
  return (
    <GradientBorder
      // Appearance
      colors={['#0066ff', '#ffdd00']} // default
      strokeWidth={3}                  // default
      borderRadius={12}                // default
      lineCapStart="square"            // 'round' | 'square' (default: 'square')
      lineCapEnd="square"              // 'round' | 'square' (default: 'square')
      // Animation
      animate={true}                   // default
      duration={2000}                  // default
      animationMode="once"             // 'once' | 'loop' (default: 'once')
      variant="default"                // 'default' | 'split' (default: 'default')
      reverse={false}                  // default
      startPosition="top-left"         // default
      // Trigger
      trigger="mount"                  // 'mount' | 'hover' | 'focus' | 'click' | 'manual'
      active={undefined}               // for trigger="manual" control
      showWhenInactive={false}         // default
      // Border Position
      borderPosition="inner"           // 'inner' | 'outer' (default: 'inner')
      borderOffset={0}                 // number | string (default: 0)
      // Ants Marching
      ants={false}                     // default
      antsDashWidth={20}               // default
      antsGapWidth={16}                // default
      antsSpeed={250}                  // default
      // Performance
      lazy={true}                      // default
      lazyRootMargin="100px"           // default
      resizeThrottle={150}             // default
      segments={200}                   // default
      // Styling
      style={{}}                       // default
      className=""                     // default
    >
      <div style={{ padding: 24, background: '#1a1a2e', borderRadius: 12 }}>
        <h2>Hello World</h2>
        <p>Content with an animated gradient border!</p>
      </div>
    </GradientBorder>
  );
}

Props

Prop Type Default Description
children ReactNode - Content to render inside the gradient border
colors string[] ['#0066ff', '#ffdd00'] Array of colors for the gradient
startPosition StartPosition 'top-left' Where the gradient begins drawing from
strokeWidth number 3 Width of the border stroke in pixels
lineCapStart LineCap 'square' Line cap for the start: 'round' or 'square'
lineCapEnd LineCap 'square' Line cap for the end/tip: 'round' or 'square'
borderRadius number 12 Border radius in pixels
segments number 200 Number of segments to divide the border into
duration number 2000 Animation duration in milliseconds
animate boolean true Whether to animate the border drawing in
trigger Trigger 'mount' What triggers the border to appear
animationMode AnimationMode 'once' Animation behavior: draw once or loop continuously
variant Variant 'default' Animation variant: draw from one point or split from both directions
reverse boolean false Reverse the animation direction
active boolean - For manual trigger control - whether the border is active
showWhenInactive boolean false Show border when not triggered (for hover/focus/click modes)
lazy boolean true Only render when visible in viewport
lazyRootMargin string '100px' Margin around viewport for lazy loading
resizeThrottle number 150 Throttle interval in ms for resize recalculations
ants boolean false Enable ants marching (dashed line) effect
antsDashWidth number 20 Width of each dash in pixels
antsGapWidth number 16 Gap between dashes in pixels
antsSpeed number 250 Speed of marching animation in ms per dash cycle
borderPosition BorderPosition 'inner' Border position: 'inner' or 'outer'
borderOffset number | string 0 Offset the border (e.g., 4, "10px", "-5px")
style CSSProperties {} Additional CSS styles for the container
className string '' Additional CSS class name for the container

Trigger

The trigger prop controls when the border appears:

  • 'mount' (default) - Border appears on component mount
  • 'hover' - Border appears on mouse hover
  • 'focus' - Border appears when a child element is focused
  • 'click' - Border toggles on click
  • 'manual' - Control with the active prop

AnimationMode

The animationMode prop controls how the border animates:

  • 'once' (default) - Draws the border once and stops
  • 'loop' - Continuously animates the gradient around the border

Variant

The variant prop controls the drawing style:

  • 'default' (default) - Draws from the start position in one direction
  • 'split' - Draws from both directions simultaneously, meeting on the opposite side

BorderPosition

The borderPosition prop controls where the border is drawn:

  • 'inner' (default) - Border is drawn inside the element bounds
  • 'outer' - Border is drawn outside the element bounds

Use borderOffset to fine-tune the position. Positive values move outward, negative values move inward. Accepts numbers (pixels) or CSS length strings like "10px" or "-0.5rem".

StartPosition

The startPosition prop accepts either a preset string or a number from 0-1:

Preset positions:

  • 'top-left' (default) - Starts at top-left corner
  • 'top' - Starts at top center
  • 'top-right' - Starts at top-right corner
  • 'right' - Starts at right center
  • 'bottom-right' - Starts at bottom-right corner
  • 'bottom' - Starts at bottom center
  • 'bottom-left' - Starts at bottom-left corner
  • 'left' - Starts at left center

Custom position: Pass a number from 0 to 1 representing a position along the border path (0 = start of path, 1 = end of path).

Examples

Multi-color gradient

<GradientBorder colors={['#ff006e', '#8338ec', '#3a86ff', '#00f5d4']}>
  <div>Rainbow gradient border</div>
</GradientBorder>

Custom start position

<GradientBorder
  colors={['#ff006e', '#00f5d4']}
  startPosition="bottom"
>
  <div>Gradient starts from bottom center</div>
</GradientBorder>

Static gradient border (no animation)

<GradientBorder colors={['#ff006e', '#8338ec']} animate={false}>
  <div>Static gradient border</div>
</GradientBorder>

Custom colors and thickness

<GradientBorder
  colors={['#9b5de5', '#f15bb5']}
  strokeWidth={4}
  borderRadius={24}
>
  <div>Purple to pink gradient</div>
</GradientBorder>

Hover trigger

<GradientBorder
  colors={['#ff006e', '#8338ec', '#3a86ff']}
  trigger="hover"
  duration={800}
>
  <div>Border appears on hover</div>
</GradientBorder>

Focus trigger (great for inputs)

<GradientBorder
  colors={['#4facfe', '#00f2fe', '#43e97b']}
  trigger="focus"
  duration={600}
>
  <input type="text" placeholder="Focus me..." />
</GradientBorder>

Click toggle

<GradientBorder
  colors={['#ff006e', '#8338ec']}
  trigger="click"
>
  <div>Click to toggle border</div>
</GradientBorder>

Continuous loop animation

<GradientBorder
  colors={['#ff006e', '#8338ec', '#3a86ff', '#00f5d4']}
  animationMode="loop"
  duration={3000}
>
  <div>Gradient continuously animates around</div>
</GradientBorder>

Split animation (draw from both directions)

<GradientBorder
  colors={['#ff006e', '#8338ec', '#3a86ff', '#00f5d4']}
  variant="split"
  duration={2000}
>
  <div>Gradient draws from both directions and meets in the middle</div>
</GradientBorder>

Ants marching (dashed border)

<GradientBorder
  colors={['#ff006e', '#8338ec', '#3a86ff']}
  ants
  animationMode="loop"
>
  <div>Marching ants border effect</div>
</GradientBorder>

Outer border

<GradientBorder
  colors={['#ff006e', '#8338ec']}
  borderPosition="outer"
  strokeWidth={4}
>
  <div>Border drawn outside the element</div>
</GradientBorder>

Border with offset

<GradientBorder
  colors={['#ff006e', '#8338ec']}
  borderOffset={8}
>
  <div>Border offset 8px outward from inner edge</div>
</GradientBorder>

Manual control

function ControlledBorder() {
  const [active, setActive] = useState(false);

  return (
    <>
      <GradientBorder
        colors={['#ff006e', '#8338ec']}
        trigger="manual"
        active={active}
      >
        <div>Programmatically controlled</div>
      </GradientBorder>
      <button onClick={() => setActive(!active)}>Toggle</button>
    </>
  );
}

Replay animation

function ReplayableCard() {
  const [key, setKey] = useState(0);

  return (
    <>
      <GradientBorder
        key={key}
        colors={['#ff006e', '#8338ec', '#00f5d4']}
        duration={1500}
      >
        <div>Animated content</div>
      </GradientBorder>
      <button onClick={() => setKey(k => k + 1)}>
        Replay Animation
      </button>
    </>
  );
}

How It Works

The component creates an SVG overlay that draws line segments along a rounded rectangle path. Each segment is colored according to a linear interpolation across all colors in the gradient. When animate is true, segments are progressively revealed to create a drawing effect. The startPosition prop allows you to control where along the border path the gradient begins.

Browser Support

This component uses:

  • ResizeObserver for responsive sizing
  • IntersectionObserver for lazy loading
  • requestAnimationFrame for smooth animations

These APIs are supported in all modern browsers.

License

MIT

About

Animated gradient borders for React components

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •