I'm Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with HTML, CSS and SVG. To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

my books

Pro CSS3 Animation book coverPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head CanonMassive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

The New DefaultsThe New Defaults — A Sass color keyword system for designers.

CSSslidyCSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

CSS3 Border-Image Explained

One of the more powerful new CSS3 properties is also one of the hardest to understand

One of the more powerful new CSS3 properties, border-image is also one of the best supported, with the exception of (all together now) IE9. It is, unfortunately, also one of the most obtuse and difficult to understand.

The explanation of how border-image works is perhaps best illustrated graphically. First, let's break down any border into its components: let's imagine an ormolu picture frame, divided up into nine tiles using two horizontal and two vertical lines. In the illustration to the right I've labeled the vertical divider lines V1 and V2, with H1 and H2 for the horizontal.

Rather than allowing you to specify a separate image for each part of a border, border-image insists that you create one image, with all the parts in place, and then slice that image up using CSS values that map to the positions of these lines.

Let's imagine that we're playing Battleship, and reference each tile created by our divisor lines. The top left corner could be referred to as "A1", the middle right section as "B3", and so on. (The middle section, B2, will be ignored by the CSS after we specify the slices for our border image.) Where the slices are placed determines our tiles. A3 will always be placed as the top right corner image for our border; C2 will be used for the bottom edge, etc.

Let's consider the sides and top of our frame, because they have rather particular, and changeable, conditions. When we apply a border to an HTML element, we don't know how big the box will be. After they are applied to our border, our corner tiles will be unaffected by size changes, but the sides, top and bottom will definitely change. We have to make a decision about the tiles that will be placed there: will they repeat as the box gets bigger, or will they stretch? This consideration will have to be part of the design of our frame, and we'll have to specify our choice when it comes to writing our CSS.

Finally, let's think about the lines that created our tiles: two horizontal, and two vertical. We need to tell CSS where those imaginary divisors are, so that it can use the information to create the tiles. We could reference their positions as either percentages or pixels away from the corners. (I would suggest in most cases that the latter is easiest, except in the case of SVG images used for border image).

Note that the chevrons on the corners of this frame means that the slices must be large enough to include those details, which increases the size of our border, and will produce a physical “matte” effect inside the physical frame, which is actually realistic for a professional mounted photograph or painting. I’ve made the interior of the frame transparent, meaning that the background-color I specify will show through.

The way in which the position of the divisors is measured and entered into the declaration is also odd: H2 is measured from the bottom of the image,  H1 from the top, V1 from the left, and V2 from the right. They are entered into the declaration in this order:

Oddly, when the values are entered as pixels, they are not followed by a px suffix, unlike almost everything else in CSS.

Given a Creative Commons image (taken by Annie Chartrand) inserted into the page with this code:

And given the border image above, the CSS applied would be something like this:

(Note that this code won't work yet – there's a few things we have to add).

You have several choices as to how the sides are treated. stretch does exactly that; repeat will repeat the tiles to fit, and round is a hybrid of both, attempting to use complete versions of the tiles for the sides, but stretching where necessary.

Importantly, you must also provide a separate, border-width declaration, to tell the browser how wide each side is so that the images can be fit in. Most resources will tell you that the dimensions used in border-width must be the same as those used for the position of the slices, i.e:

But I've found that using a single border-width value will effectively scale the border dimensions:

Remember that you'll also need a plain border to fall back on should the image for the tiles not load or your visitors use IE: I'd suggest specifying a border approximating the thickness of the image tiles, and using its dominant color, with perhaps a lesser-used border-style thrown in.

So the complete code for the effect shown at the top of this page would be:

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.