CSS3 Border Images for Beautiful, Flexible Boxes

Louis Lazaris

The CSS3 buzz is in full swing, and many of CSS3’s most useful properties are receiving a fair bit of attention. Properties like border-radius, text-shadow, custom gradients, and even CSS3 transitions have been shown to be quite practical, resolving real-world design issues with minimal markup and maintainable code.

One CSS3 property that’s been overlooked in this area, however, is the border-image property. The irony here is that what makes this property so useful, is exactly what makes it extremely confusing.

In this article, I’m going to attempt to demystify this very practical property. I’ll demonstrate how it can be implemented using some more attractive examples than what’s been attempted so far by well-meaning blogs and websites.

The Syntax

Currently, the only browser support for CSS3’s border images is by means of the border-image shorthand notation. Here’s what the syntax looks like, with the necessary proprietary syntax included:

.border-image-example {  -webkit-border-image: url(border-image.jpg) 45 20 45 30 repeat;  -moz-border-image: url(border-image.jpg) 45 20 45 30 repeat;  border-image: url(border-image.jpg) 45 20 45 30 repeat;}

The notation is broken up into three sections. The first is the URL that points to the image. This should be familiar to most CSS developers, since it’s the same syntax that’s used for the CSS background property.

The next section (the four numeric values) represents the border-image-slice property. The spec explains:

The four border-image-slice values represent inward offsets from the top, right, bottom, and left edges of the image respectively, dividing it into nine regions: four corners, four edges, and a middle.

So, the single image you provide will be sliced into nine pieces, which will then be used to construct the border. The way the slices are made is illustrated in Figure 1, “The border-image-slice model”.

Figure 1. The border-image-slice model

The border-image-slice model


You’ll notice that the lines that create the regions are individually numbered. As these imaginary lines intersect, they create the nine areas into which the image will be sliced.

So how do the four numeric values correlate to the image shown above?

  • The first value is the distance (in pixels or as a percentage) between the topmost edge of the image and line #1.

  • The second value is the distance between the rightmost edge and line #2.

  • The third value is the distance between the bottommost edge and line #3.

  • And finally, the fourth value is the distance between the leftmost edge and line #4.

note: Values and Units

It should be noted that the syntax requires the % symbol to be included when using percent values, but the px should be omitted when using pixel values.

The corner slices of your image are handled in a straightforward way, with each used in the respective corner of the element to which you’ve applied the border-image. The middle sections, however, are trickier; after all, the sizes could potentially be any length. That’s where the last value in the border-image shorthand notation comes into play. It will determine how the non-corner parts of the image should be handled. The four possible values are stretch, repeat, round, and space.

The first two are fairly self-explanatory: stretch will stretch the slice to fill the space required, and repeat will tile it. The last two (round and space) are variants of repeat; they specify the behavior to adopt in the event that the space available doesn’t allow for a whole number of tiled slices. With repeat, the last tile will simply be cut off once all the space has been filled. By contrast, if you use space, the extra space will be distributed around each tile; and if you use round, the image will be stretched a little so that a whole number or slices suffice to fill the space.

You can also specify two values for this property, with the first applying to the top and bottom sides, and the second to the left and right sides:

border-image: url(border-image.jpg) 45 20 45 30 repeat stretch;

For an in-depth explanation of how these values are used to construct the border, check out the specification.

How Does It Work?

In order for border-image to work correctly, the element to which it’s applied must have the border (or border-width) property set with four values corresponding to the values given in the shorthand notation. (Otherwise your image slices will be stretched to fill the border width, which is rarely what you want).

The four values behave similarly to margin and padding values; it’s unnecessary to declare all four values explicitly. You could declare a single value, and that will represent all four. Or you could include just the first two values, and the two omitted values will match the ones declared. Thus, the following two examples would have the exact same results:

.border-image-example {border-image: url(bg-border.jpg) 45 20 45 20 repeat;}.border-image-example {border-image: url(bg-border.jpg) 45 20 repeat;}

Some Demonstrations

As mentioned, many of the examples of border-image shown on various blogs are downright ugly. For this article, I decided to create a few cleaner and more practical examples that demonstrate how valuable this property will become when it’s fully supported by all in-use browsers. Have a look, and be sure to view the source to get a view of what exactly goes into these demos.

Three different images are used to create the border images shown on the demo page. Figure 2, “The three images used in the demo” shows all three images, so you can see how flexible this property really is.

Figure 2. The three images used in the demo

The three images used in the demo


The three images above are all quite small, but because of the flexibility of the border-image property, they can suit any sized box, as long as the settings are declared correctly in the CSS.

Constructing the Images to Be Used

Admittedly, creating the images necessary for border images can be a bit tedious at first. But once you understand how the property works, it’s fairly easy to create the mockup of your bordered box, then condense the image down to a bare minimum for insertion into the page.

To understand exactly how the images are constructed, here’s the first image blown up and divided into sections:

Figure 3. A closer look at one of the demo images

A closer look at one of the demo images


The red boxes indicate the four corner sections, while the areas between the boxes (in this case just a single pixel) represent the parts of the border that will either repeat or stretch to accommodate the size of the box.

In this example, a single pixel between the corner images is enough, because the repeating border is, well, a single pixel.

On the demo page, you’ll notice a variation on the third example, which has paw prints surrounding the entire image and with whitespace separating the paw prints. In such a case, it’s more challenging to get the border image to work correctly for different sized boxes unless you use the round or space values in your CSS notation. In fact, if you view the examples in Chrome or Safari (which lack support for the round value), you’ll notice that some of the paw prints in the third example are cut off near the corners; conversely, Firefox 3.5+ and Opera 10.5+ (both of which support the value round) are without this flaw.

Remember Your Fallback Options!

Because of the lack of support across all modern browsers, it’s unlikely that image borders will be used extensively at this point. If you do decide to use them, don’t forget to test in nonsupporting browsers, and provide respectable fallback options for the look and size of the border.

For a more detailed discussion of the border-image property, be sure to check out the resources below:

Do you know of any examples of border-images in use on live sites? Please let us know in the comments.

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • Yossis

    Great Great tutorial!!! thank you for sharing your knowledge

  • Yossis

    Great Great tutorial!!! thank you for sharing your knowledge

  • Yossis

    Great Great tutorial!!! thank you for sharing your knowledge