Skip to content

Border Gradient

Apply gradient borders using CSS background clipping — no pseudo-elements or JavaScript. Supports linear, radial, and conic gradients with colour stop positions and 8 interpolation modes. For animated spinning borders, see Border Spin.

Import

Included in @import 'tw-jib-css'. To import individually:

css
@import 'tw-jib-css/border-gradient';

Quick Reference

Class Styles
border-linear-to-t--tw-border-gradient: linear-gradient(to top, var(--tw-border-gradient-stops))
border-linear-to-tr--tw-border-gradient: linear-gradient(to top right, var(--tw-border-gradient-stops))
border-linear-to-r--tw-border-gradient: linear-gradient(to right, var(--tw-border-gradient-stops))
border-linear-to-br--tw-border-gradient: linear-gradient(to bottom right, var(--tw-border-gradient-stops))
border-linear-to-b--tw-border-gradient: linear-gradient(to bottom, var(--tw-border-gradient-stops))
border-linear-to-bl--tw-border-gradient: linear-gradient(to bottom left, var(--tw-border-gradient-stops))
border-linear-to-l--tw-border-gradient: linear-gradient(to left, var(--tw-border-gradient-stops))
border-linear-to-tl--tw-border-gradient: linear-gradient(to top left, var(--tw-border-gradient-stops))
border-linear-<angle>--tw-border-gradient: linear-gradient(<angle>deg, var(--tw-border-gradient-stops))
border-radial--tw-border-gradient: radial-gradient(var(--tw-border-gradient-stops))
border-radial-[<value>]--tw-border-gradient: radial-gradient(<value>, var(--tw-border-gradient-stops))
border-conic-<angle>--tw-border-gradient: conic-gradient(from <angle>deg, var(--tw-border-gradient-stops))

Basic Usage

Linear gradient border

Use border-linear-to-{direction} with border-from-{color} and border-to-{color} to create a gradient border:

border-linear-to-r border-from-pink-500 border-to-cyan-500

With a background colour

Border gradients work alongside Tailwind's bg-* utilities. When you apply a bg-* class, the module layers your background inside the border gradient automatically.

Solid background colours

bg-white
bg-gray-900
bg-sky-100

Gradient backgrounds

Tailwind gradient backgrounds and border gradients coexist — the background gradient layers inside the padding area while the border gradient fills the border area. The background and border gradient types don't need to match:

bg-linear + border-linear
bg-linear + border-conic
bg-radial + border-linear
bg-conic + border-radial

Inherited backgrounds

The background colour does not inherit from parent elements. The --tw-bg-color custom property is registered with inherits: false, so a child element without its own bg-* class gets the initial value (canvas) rather than the parent's colour:

Parent: bg-slate-800

No bg-* class (canvas)
bg-slate-800 (explicit)

Transparent and semi-transparent backgrounds

The border-gradient technique works by stacking two background layers — a padding-box layer (your background) on top of a border-box layer (the gradient). A transparent or semi-transparent background lets the gradient layer show through into the content area, not just the border:

bg-white (opaque)
bg-white/50 (gradient bleeds through)
bg-transparent (fully visible)

This is inherent to the clipping technique — the padding-box layer must be fully opaque to mask the gradient behind it. If you want a see-through content area with only a gradient border, this approach won't work; you'd need a pseudo-element or border-image technique instead.

What doesn't work

WARNING

Backgrounds set outside Tailwind's bg-* classes won't show through the border gradient. The border-gradient utilities set a background shorthand that replaces any background or background-color from custom CSS classes or inline styles.

A background set via a custom CSS class or inline style is overwritten by the border-gradient utility's background shorthand. The --tw-bg-image property stays at its initial value (canvas), so the element loses its intended background:

html
<!-- ✗ Custom class — background is overwritten -->
<style>.my-card { background: #e0f2fe; }</style>
<div class="my-card border-4 border-linear-to-r border-from-pink-500 border-to-cyan-500">
  Background will be canvas, not #e0f2fe
</div>

<!-- ✗ Inline style — same issue -->
<div style="background-color: #e0f2fe" class="border-4 border-linear-to-r border-from-pink-500 border-to-cyan-500">
  Background will be canvas, not #e0f2fe
</div>

Workarounds

Route the colour through Tailwind's bg-* pipeline so it feeds into --tw-bg-image:

html
<!-- ✓ Arbitrary value -->
<div class="bg-[#e0f2fe] border-4 border-linear-to-r border-from-pink-500 border-to-cyan-500">
  ...
</div>

<!-- ✓ Custom property via bare-value syntax -->
<div class="bg-(--my-color) border-4 border-linear-to-r border-from-pink-500 border-to-cyan-500">
  ...
</div>

Or set --tw-bg-image directly to bypass the bg-* utility:

html
<!-- ✓ Setting the custom property directly -->
<div style="--tw-bg-image: linear-gradient(#e0f2fe 0 0)" class="border-4 border-linear-to-r border-from-pink-500 border-to-cyan-500">
  ...
</div>

Gradient Direction

Directional

Use border-linear-to-{t|tr|r|br|b|bl|l|tl} for predefined directions:

border-linear-to-t
border-linear-to-tr
border-linear-to-r
border-linear-to-br
border-linear-to-b
border-linear-to-bl
border-linear-to-l
border-linear-to-tl

Custom angle

Use border-linear-{angle} for a specific angle in degrees. Prefix with - for negative angles:

border-linear-45
border-linear-65
border-linear-135
-border-linear-45

Colour Stops

Setting gradient colours

Use border-from-{color}, border-via-{color}, and border-to-{color} to set gradient colour stops. These accept any Tailwind colour, including transparent and inherit:

border-from-pink-500 border-to-blue-500
border-from-pink-500 border-via-yellow-400 border-to-blue-500
border-from-blue-500 border-to-transparent
border-from-inherit (resolves to registered initial value)

Setting gradient stop positions

Use border-from-{n}%, border-via-{n}%, and border-to-{n}% to set where each colour stops:

border-from-10% border-via-30% border-to-90%

Radial Gradients

Use border-radial for a gradient that radiates from the centre. Use bracket notation to set a custom position — either percentage-based or keyword-based:

border-radial border-via-30% border-to-100%
border-radial-[at_25%_25%]
border-radial-[at_top]

Conic Gradients

Use border-conic-{angle} for a gradient that sweeps around a centre point. Prefix with - for negative start angles:

border-conic-0
border-conic-90
border-conic-180
-border-conic-45
border-conic/longer

Interpolation Modes

Control how colours blend using the slash modifier on the gradient type. The default is oklab. See the Colour Spaces guide for an overview of how these spaces differ.

Linear

/srgb
/hsl
/oklab
/oklch
/longer
/shorter
/increasing
/decreasing

Radial

/srgb
/hsl
/oklab
/oklch
/longer
/shorter
/increasing
/decreasing

Conic

/srgb
/hsl
/oklab
/oklch
/longer
/shorter
/increasing
/decreasing

Available modifiers: /srgb, /hsl, /oklab, /oklch, /longer, /shorter, /increasing, /decreasing

Choosing an interpolation mode

See Colour Spaces for a deeper look at how each space affects blending.

ModeBest for
/oklab (default)Smooth, perceptually uniform blends. No hue shifts. Best general-purpose choice.
/srgbClassic RGB blending. Can produce muddy midpoints between complementary colours.
/hslHue-based blending. Predictable hue transitions but can produce unexpected bright or grey bands.
/oklchPerceptually uniform with hue control. Good for rainbow-like gradients.
/longerTakes the long way around the hue wheel in oklch. Creates rainbow effects between two colours.
/shorterShortest path around the hue wheel (default hue interpolation in oklch).
/increasingAlways moves clockwise around the hue wheel.
/decreasingAlways moves counter-clockwise around the hue wheel.

Using a custom value

Use bracket notation for custom colours and angles. Colour stops accept any CSS colour format — hex, rgb(), hsl(), oklch(), etc.:

border-linear-[135deg] border-from-[#ff6b35]
border-from-[oklch(0.6_0.25_330)] border-to-[oklch(0.7_0.2_200)]
border-from-[hsl(330,80%,50%)] border-to-[hsl(200,80%,50%)]

Using a custom variable

Reference CSS custom properties with the typed bare-value syntax (type:--var). The type hint tells Tailwind how to interpret the variable:

border-from-(color:--brand-from) border-to-(color:--brand-to)

All border gradient utilities that accept custom properties:

UtilityType hintExample
border-from-*colorborder-from-(color:--brand-from)
border-via-*colorborder-via-(color:--brand-accent)
border-to-*colorborder-to-(color:--brand-to)
border-from-*percentageborder-from-(percentage:--stop-start)
border-to-*percentageborder-to-(percentage:--stop-end)
border-linear-*numberborder-linear-(number:--angle)
border-conic-*numberborder-conic-(number:--start-angle)

Applying conditionally

Hover and focus states

Prefix a border gradient utility with a state variant like hover:* to only apply it in that state:

Hover to shift gradient

Border Width

The gradient fills whatever border width you set. Thicker borders show more of the gradient:

border (1px)
border-2
border-4
border-8

Border Style and Border Colour

The border-gradient technique renders the gradient as a background layer clipped to border-box and sets border-color: transparent by default. The gradient is always present underneath — what you see depends on how border-color and border-style combine to paint over it.

Default (transparent border colour)

With border-color: transparent (the default), all border styles look identical — the gradient shows through the entire border area because nothing is painted on top of it:

solid
dashed
dotted
double
groove
ridge
inset
outset

Solid border colour hides the gradient

Setting a solid border-color with a Tailwind colour class (e.g. border-amber-500) or a custom property (e.g. border-(color:--var)) paints over the gradient completely. The border colour is drawn on top of the gradient background layer, so with border-solid the gradient is fully hidden:

solid
dashed
dotted
double
groove
ridge
inset
outset

With dashed, dotted, and double, the solid colour only covers the painted segments — the gradient shows through the gaps between dashes, dots, and double lines. The groove, ridge, inset, and outset styles derive their 3D shading from the border colour, so the gradient peeks through where the browser lightens or darkens the colour.

Semi-transparent border colour

A semi-transparent border colour (e.g. border-amber-500/50) tints the gradient where the colour is painted, and the gradient shows through at full strength in the gaps:

solid
dashed
dotted
double
groove
ridge
inset
outset

How It Works

The gradient border technique uses CSS background clipping. A transparent border is set, then two background layers are stacked:

  1. Padding-box layer — your background colour, clipped to the content + padding area
  2. Border-box layer — the gradient, filling the entire box including the border area

The border area shows the gradient because the padding-box background doesn't cover it. This is a pure CSS technique that works with border-radius and doesn't require pseudo-elements.

For animated spinning borders, see Border Spin.