CSS border-image-slice Property

This property determines how to divide a source image into nine regions to create a scalable border.

selector { border-image-slice: [<number> | <percentage>]{1,4} && fill?; }
<number> Represents edge offsets in pixels for raster images or coordinates for vector images.
<percentage> Specifies the offset as a percentage of the source image width or height.
fill Preserves the middle region of the sliced image to be used as a background for the element.

Code Examples

A basic example showing how to slice a border image at 30 pixels from each edge.

<div style="border: 30px solid #cccccc; border-image-source: url('https://www.adamkhoury.com/images/border_frame.png'); border-image-slice: 30; width: 300px; padding: 20px;">
  This element uses a 30-pixel slice to create a custom decorative frame.
</div>

An advanced example using the fill keyword and JavaScript to dynamically change the slice value on hover.

<div id="ui-box" style="border: 20px solid #333333; border-image-source: url('https://www.adamkhoury.com/images/panel_ui.png'); border-image-slice: 20 fill; width: 400px; color: #ffffff; padding: 25px;">
  Advanced UI panel using the fill keyword.
</div>

<script>
const box = document.getElementById("ui-box");
box.addEventListener("mouseenter", () => {
  box.style.borderImageSlice = "40 fill";
  box.style.color = "#ffff00";
});
box.addEventListener("mouseleave", () => {
  box.style.borderImageSlice = "20 fill";
  box.style.color = "#ffffff";
});
</script>

Pro Tip

You can use percentages to make your slices relative to the image size. This is a lifesaver if you are working with SVG border images that need to scale perfectly regardless of the viewport size. Also, remember that you can combine different values for each side to handle asymmetrical designs or unique frame styles.

Deep Dive

Think of your source image like a Tic-Tac-Toe board. This property draws four invisible lines—top, right, bottom, and left—to cut that image into nine distinct zones. You get four corners, four edges, and a center. The corners stay fixed at the corners of your element, while the edges stretch or repeat to fill the gaps between them. By default, the middle piece is tossed out, but you can keep it by adding the "fill" keyword. If you use one value, it cuts all sides equally. If you use four, it follows the TRBL (Top, Right, Bottom, Left) clock order. It is the secret sauce for making responsive boxes with custom graphics that do not look distorted when the container grows.

Best Practices

Always use a high-quality 9-slice image designed for scaling. If your image is 90x90 pixels and you want perfectly equal slices, use a value of 30. This ensures the corners stay crisp. Also, make sure to define a standard border-style and border-width as a fallback. It is like building a house; you need the wooden frame before you can hang the fancy custom siding.

Common Pitfalls

The biggest mistake is adding "px" after your numbers. In the world of border-image-slice, raw numbers are already treated as pixels. Adding the unit will cause the browser to ignore the declaration entirely. Another common trip-up is forgetting the "fill" keyword. Without it, your element center will be transparent, which is a headache if you expected the middle of your image to act as the element background.

Accessibility

Visual borders help users identify interactive areas or grouped content. If your border image contains important visual cues, make sure the colors contrast well against the page background for users with low vision. Since this is a decorative property, it does not convey semantic meaning to screen readers, so do not rely on it alone to communicate state changes.

Dev Data Table: border-image-slice property

default 100%
animatable no
inherited no
experimental no
year_intro 1999
year_standard 2011
js_syntax_1 element.style.borderImageSlice = "30";
js_syntax_2 element.style.setProperty("border-image-slice", "30");
js_note When using JavaScript, provide the value as a string. Do not include units like px because raw numbers are interpreted as pixels for raster images by default.
browsers { "Chrome": 15, "Edge": 11, "Firefox": 15, "Safari": 6, "Opera": 15, "Chrome Android": 18, "Safari on iOS": 6, "Samsung Internet": 1, "Opera Mobile": 14 }
results render here...