In short
CSS border images let you use an image or gradient as an element's border. Learn border-image-source, slice, width, outset and repeat, gradient borders, and rounded gradient borders. What is a CSS border image? A normal border is a line in one color.
CSS border images let you use an image or gradient as an element's border. Learn border-image-source, slice, width, outset and repeat, gradient borders, and rounded gradient borders.
What is a CSS border image?
A normal border is a line in one color. A border image replaces that line with a picture or a gradient. The browser takes your image, cuts it into nine pieces, and uses them to build a frame around the element, like a picture framer cutting corner pieces and side strips from one long piece of wood.
Here's the shortest useful example, a gradient border:
<div class="promo">Limited offer: 20% off this week only!</div>
.promo {
padding: 20px;
border: 6px solid transparent;
border-image: linear-gradient(90deg, #f97316, #ec4899, #8b5cf6) 1;
}
You'll see a box with a border that fades from orange through pink to purple. Note the border: 6px solid transparent; line. A border image needs a border width and a border style to have space to draw in. Without a style, the border width is 0 and nothing appears.
The five border-image properties
border-image is a shorthand for five properties:
| Property | What it does | Example |
|---|---|---|
border-image-source | The image or gradient to use. | url("frame.png") |
border-image-slice | Where to cut the image into 9 pieces, measured inward from each edge. | 30 or 30 fill |
border-image-width | How thick the image border is drawn. Defaults to the border-width. | 20px |
border-image-outset | How far the border image reaches outside the border box. | 10px |
border-image-repeat | How the side pieces fill the edges. | stretch, repeat, round, space |
The shorthand order is: border-image: source slice / width / outset repeat;. You'll usually only write the source, slice and repeat.
How border-image-slice works
border-image-slice is the tricky part. Imagine drawing four lines on your image, a set distance in from each edge. These lines cut it into nine pieces, like a tic-tac-toe board:
+--------+-------------+--------+
| corner | top edge | corner |
+--------+-------------+--------+
| left | middle | right |
| edge | (not shown) | edge |
+--------+-------------+--------+
| corner | bottom edge | corner |
+--------+-------------+--------+
- The four corners go into the corners of the border, unchanged in shape.
- The four edges are stretched or repeated along the sides.
- The middle is thrown away, unless you add the keyword
fill, which paints it behind the content.
Slice values are numbers without units (meaning image pixels) or percentages. border-image-slice: 30 cuts 30 pixels in from every side. For a gradient, which has no pixels, 1 is the usual value: it uses a thin slice from each edge, so the gradient flows smoothly around the box.
border-image-repeat values
| Value | How the side pieces fill the edge |
|---|---|
stretch | Stretches one piece along the whole side (the default). |
repeat | Tiles the piece; tiles at the ends may be cut off. |
round | Tiles the piece and resizes it slightly so a whole number of tiles fits. Usually the nicest. |
space | Tiles whole pieces and spreads the extra space between them. |
A fancy frame example
Let's build a decorative frame from a small SVG image. The image is 30 by 30 pixels: a brown square with big gold dots in the corners and small gold dots in the middle of each side. We write it straight into the CSS as a data URL, so you don't need a separate file.
<figure class="frame">
<img src="https://picsum.photos/id/1062/400/300" alt="A dog sitting on a sofa">
</figure>
.frame {
width: fit-content;
margin: 24px auto;
border: 20px solid #b45309;
border-image-source: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Crect width='30' height='30' fill='%23b45309'/%3E%3Cg fill='%23fde68a'%3E%3Ccircle cx='5' cy='5' r='4'/%3E%3Ccircle cx='25' cy='5' r='4'/%3E%3Ccircle cx='5' cy='25' r='4'/%3E%3Ccircle cx='25' cy='25' r='4'/%3E%3Ccircle cx='15' cy='5' r='2'/%3E%3Ccircle cx='5' cy='15' r='2'/%3E%3Ccircle cx='25' cy='15' r='2'/%3E%3Ccircle cx='15' cy='25' r='2'/%3E%3C/g%3E%3C/svg%3E");
border-image-slice: 10;
border-image-repeat: round;
}
.frame img {
display: block;
}
The photo now has a 20px brown frame with large gold dots in the four corners and a neat row of small gold dots along every side. Here's what happens: slice: 10 cuts the 30px image into a 3 by 3 grid of 10px pieces. Each corner piece holds one big dot. Each edge piece holds one small dot, and round repeats it along the sides. The pieces are scaled up from 10px to the 20px border width. If the image fails to load, the solid brown border is the fallback.
Here's a second, shorter example with a striped gradient, like a warning sign:
.warning {
padding: 16px;
border: 12px solid #facc15;
border-image: repeating-linear-gradient(45deg, #facc15 0 10px, #1e293b 10px 20px) 12;
}
The box gets a yellow-and-black striped frame. border-image-outset could push the frame outward, for example border-image-outset: 6px;, without changing the layout, a bit like an outline.
Gradient borders with rounded corners
There's one big limit: border images ignore border-radius. The corners are always square. If you want a rounded gradient border, use this popular alternative trick with two background layers:
<button class="glow-btn">Join the beta</button>
.glow-btn {
padding: 12px 28px;
font-size: 1rem;
border: 3px solid transparent;
border-radius: 999px;
background:
linear-gradient(white, white) padding-box,
linear-gradient(90deg, #06b6d4, #8b5cf6, #ec4899) border-box;
}
The button is a white pill with a rounded rainbow border. The first layer (white) is clipped to the padding box, so it covers everything except the border area. The second layer (the gradient) fills the whole box including the border, so it shows only in the transparent 3px border ring. Because it's a background, it respects border-radius. You learned about padding-box and border-box in the Multiple Backgrounds lesson.
Common mistake: Adding
border-radiusto an element withborder-imageand wondering why the corners stay square. Use the two-background trick above whenever you need rounded corners.
Tip: Want to check what each slice value does? Try the border-image examples on MDN's border-image page and change the numbers live.
Practice exercise
Create three "award badges": one with a gold gradient border made with border-image, one with a striped repeating-linear-gradient frame, and one round badge with a gradient border using the two-background trick. Then add fill to the first badge's slice and see what changes.
Hint: with fill, the middle of the gradient paints behind the content, so you may need a darker text color.
Key takeaways
- A border image replaces the border line with an image or gradient cut into nine pieces.
- It needs a border width and style, such as
border: 10px solid transparent;. border-image-slicesets where to cut; for gradients use1, and addfillto paint the middle.border-image-repeat: roundtiles edge pieces neatly;stretchis the default.- Border images ignore
border-radius; use the padding-box/border-box background trick for rounded gradient borders.