CSS propertyBox model

border-image

Replaces a plain border with an image or gradient sliced into corners and edges.

Initial value
none 100% / 1 / 0 stretch
Inherited
No
Animatable
partially: slice, width, and outset yes, image and repeat no
Applies to
all elements except internal table elements with border-collapse: collapse
JavaScript
element.style.borderImage = "linear-gradient(#7c3aed, #0ea5e9) 1"
On this page

Example

#
CSS
.plan {
  padding: 16px;
  border: 3px solid #7c3aed;
  border-image: linear-gradient(135deg, #7c3aed, #0ea5e9, #10b981) 1;
}
Preview

Definition and usage

#

The border-image property paints a border from an image instead of a line. The browser cuts the image into nine pieces, like a tic-tac-toe board: the four corners land in the frame’s corners, the four edges get stretched or repeated along the sides, and the center is left empty by default.

It’s shorthand for five properties: border-image-source (the image or gradient), border-image-slice (where to cut: a number with no unit means image pixels, percentages also work), border-image-width (the frame’s thickness), border-image-outset (how far to push the frame outward), and border-image-repeat (how to fill the sides: stretch, repeat, round, or space). The keyword fill on the slice also paints the center.

The image lands where the border would be, so the element needs a border with a width and a style, for example border: 12px solid #7c3aed. Without a style, the border’s width is 0 and the image won’t show, and the color from that declaration serves as a fallback if the image fails to load.

Today you’ll most often see border-image paired with a gradient: linear-gradient(…) 1 gives a colorful frame with no image files at all. Just remember that border-radius doesn’t round an image border. A rounded gradient frame is built from two background layers instead, shown in the extra example.

Syntax

#
Syntax
border-image: <source> || <slice> [ / <width> | / <width>? / <outset> ]? || <repeat>;

Values

#
  • none

    No image: a plain gray border from the border declaration shows instead. On the left is the 60 × 60px source image the other examples use, with cut lines every 20px.
  • stretch

    edge repeat

    The --frame variable holds the image on the left, and the 20 slice cuts it every 20px. The edges stretch along the whole side, so the circles turn into ellipses. This is the default value.
  • repeat

    edge repeat

    Edge tiles repeat outward from the middle of the side. They can get cut off halfway at the corners.
  • round

    edge repeat

    Tiles repeat and scale slightly so a whole number of them fits on the side. Nothing gets cut off.
  • space

    edge repeat

    Only whole tiles, with no scaling, stay on the side, and the leftover space is spread evenly between them.
  • fill

    slice with fill

    The fill keyword on the slice also paints the image’s center, the blue circle, repeated here across the whole interior like an extra background.
  • linear-gradient(…) 1

    gradient as source

    A gradient instead of a file. The 1 slice makes the edges form a continuous, colorful frame.

Values in practice

#

none

No image: a plain gray border from the border declaration shows instead. On the left is the 60 × 60px source image the other examples use, with cut lines every 20px.
.demo { border-image: none; }

stretch

The --frame variable holds the image on the left, and the 20 slice cuts it every 20px. The edges stretch along the whole side, so the circles turn into ellipses. This is the default value.
.demo { border-image: var(--frame) 20 stretch; }

repeat

Edge tiles repeat outward from the middle of the side. They can get cut off halfway at the corners.
.demo { border-image: var(--frame) 20 repeat; }

round

Tiles repeat and scale slightly so a whole number of them fits on the side. Nothing gets cut off.
.demo { border-image: var(--frame) 20 round; }

space

Only whole tiles, with no scaling, stay on the side, and the leftover space is spread evenly between them.
.demo { border-image: var(--frame) 20 space; }

fill

The fill keyword on the slice also paints the image’s center, the blue circle, repeated here across the whole interior like an extra background.
.demo { border-image: var(--frame) 20 fill round; }

linear-gradient(…) 1

A gradient instead of a file. The 1 slice makes the edges form a continuous, colorful frame.
.demo { border-width: 6px; border-image: linear-gradient(135deg, #7c3aed, #0ea5e9) 1; }

More examples

#
Rounded border with a gradient
CSS
.plan {
  padding: 16px;
  border: 3px solid transparent;
  border-radius: 16px;
  background:
    linear-gradient(#18181b, #18181b) padding-box,
    linear-gradient(135deg, #7c3aed, #0ea5e9, #10b981) border-box;
}
Preview

border-image ignores border-radius, so a rounded frame is built differently. The first background layer fills the inside (padding-box), and the second, with the gradient, shows through only the transparent border (border-box).

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • With a gradient, always provide a slice, usually 1. The shorthand without a slice defaults to 100%: the whole image then lands in the corners, and the sides stay empty.
  • For decorative patterned frames, choose round or space. With repeat, tiles at the corners are often cut off, and stretch distorts the pattern.
  • You can’t round a frame with border-image. Use a transparent border and two background layers with padding-box and border-box instead.

Related entries

#

Spotted a mistake or missing an example? Write to us.