CSS border-image-repeat Property

This property defines how the middle and edge slices of a border image are scaled or tiled to match the dimensions of the element.

selector { border-image-repeat: stretch | repeat | round | space; }
stretch Stretches the source image slices to fill the entire length of the border area.
repeat Tiles the image slices to fill the border area, potentially cutting off the last tile if it does not fit perfectly.
round Tiles the image slices and scales them slightly so that a whole number of tiles fit perfectly without being clipped.
space Tiles the image slices and distributes extra whitespace between the tiles to fill the border area evenly.

Code Examples

A basic example showing the round value used to create a perfectly fitted repeating border pattern.

<div style="border: 20px solid #222222; border-image-source: url('https://www.adamkhoury.com/images/pattern.png'); border-image-slice: 30; border-image-repeat: round; padding: 20px;">
  The border image on this element is set to round, ensuring tiles are never clipped.
</div>

An advanced example using JavaScript to toggle between stretch and repeat modes to demonstrate visual differences.

<div id="uiBox" style="border: 40px solid #333333; border-image-source: url('https://www.adamkhoury.com/images/frame.png'); border-image-slice: 40; border-image-repeat: stretch; padding: 20px; transition: all 0.5s;">
  Dynamic Border Repeat Control
</div>
<button onclick="updateRepeat()">Toggle Repeat Mode</button>

<script>
function updateRepeat() {
  const el = document.getElementById("uiBox");
  const isStretch = el.style.borderImageRepeat === "stretch";
  el.style.borderImageRepeat = isStretch ? "repeat" : "stretch";
  el.style.borderColor = isStretch ? "#ff0000" : "#333333";
}
</script>

Pro Tip

You can mix and match behaviors for different axes. For example, using "border-image-repeat: round stretch;" will tile the top and bottom borders cleanly while stretching the side borders to fit.

Deep Dive

Think of your border image like a piece of patterned elastic. By default, CSS uses "stretch", which grabs the image and yanks it until it reaches the corners of your box. If your image is a pattern, it ends up looking distorted. By switching to "repeat", you are basically using the image like wallpaper, tiling it along the edge. However, "repeat" often results in an ugly chopped-off tile at the corners. That is where "round" comes in handy. It acts like a smart tailor, slightly stretching or squashing the tiles so an exact number of them fit into the available space perfectly. You can provide one value for all sides, or two values to handle the horizontal and vertical edges differently.

Best Practices

Use "round" when you have a repeating pattern that needs to look seamless, as it prevents tiles from being sliced in half. Always ensure you have a standard "border" shorthand property defined as a fallback for browsers that fail to load the image or do not support the property.

Common Pitfalls

The property will seem like it is doing nothing if you have not properly defined the "border-image-slice" property. Without slices, there is no edge content for the browser to repeat. Also, remember that "border-image" properties usually override the standard "border-style", but you still need a "border-width" for the image to have a physical area to occupy.

Accessibility

Avoid using border images with high-contrast, vibrating patterns that could trigger issues for users with photosensitive epilepsy. Ensure the border does not visually bleed into the content area, making the text harder to read for users with low vision.

Dev Data Table: border-image-repeat property

default stretch
animatable no
inherited no
experimental no
year_intro 1999
year_standard 2015
js_syntax_1 element.style.borderImageRepeat = "round";
js_syntax_2 element.style.setProperty("border-image-repeat", "repeat");
js_note When using multiple values for horizontal and vertical repeat in JavaScript, treat the property as a single string containing both values separated by a space.
browsers { "Chrome": "15", "Edge": "12", "Firefox": "15", "Safari": "6", "Opera": "15", "Chrome Android": "18", "Safari on iOS": "6", "Samsung Internet": "1.0", "Opera Mobile": "14" }
results render here...