Setting CSS3 Border-Radius with Slash Syntax

Louis Lazaris

What could I possibly say about the CSS3 border-radius property that hasn’t been said before? Well, I can’t claim that anything I’ll be saying in this article will be completely new to anyone who regularly reads articles covering front-end technologies.

Sometimes, however, the apparent simplicity of a particular CSS3 property might blind us to the fact that there can be a whole lot more going on than we think.

That’s exactly what this short article will help to establish—specifically in relation to the border-radius property.

But don’t worry—I’ll go through this carefully, covering some border-radius basics first, to ease into the discussion.

Before I get into the meat of things, I’m happy to announce that I’ve recently had the privilege of co-authoring an exciting new book project published by SitePoint. It’s called HTML5 and CSS3 for the Real World and is scheduled for a late May launch. Naturally, border-radius will be covered in that upcoming book, but I thought it would be nice to expand on that topic here and provide a little extra for those interested in delving into some of the finer points associated with this property.

The border-radius Basics

border-radius is a pretty simple property to use, and has 100% support across all modern browsers, and is even supported in quite a few earlier browser versions. Here’s how the syntax looks in its most basic shorthand form:

#element {

  border-radius: 10px;

}

That will put a 10px radius (i.e., a rounded edge) on each corner of the targeted element. If you want to specify a different value for each corner, you can do this:

#element {

  border-radius: 10px 5px 20px 16px;

}

The values start with the top-left and move clockwise.

Just like the margin and padding properties you can, of course, omit one or two values and the existing values will be used to determine the omitted ones:

#element {

  border-radius: 10px 5px 20px;

}

In that last example, although I’ve omitted the value for the bottom-left corner, the bottom-left corner will inherit its radius value from the one specified for top-right (the second value). Similarly, if you omitted the third and fourth values, then the third value (bottom-right) would inherit from the first (top-left).

Finally, you can also declare each corner individually using longhand syntax, like this:

#element {

  border-top-left-radius: 10px;

  border-top-right-radius: 5px;

  border-bottom-right-radius: 20px;

  border-bottom-left-radius: 16px;

}

Pretty simple. And I’ll bet you already knew all of that, didn’t you?

Now, let’s bring in a little complexity so we can really get to know this CSS3 property.

Different Values for Horizontal and Vertical Radii

Because the standard way of declaring the border-radius values (discussed above) has become so widespread, you may not be aware of an alternative syntax for this property.

Take a look at the following code example:

#element {

  border-radius: 55px / 25px;

}

When I first saw that style of syntax, with the slash in between the two values, my first reaction was: That can’t be right! But it is. Here’s how the spec explains it:

“If values are given before and after the slash, then the values before the slash set the horizontal radius and the values after the slash set the vertical radius. If there is no slash, then the values set both radii equally.”

Below is an image of what the element looks like with the above syntax, and with dimensions of 200px by 200px and a gray background. Bear in mind, a CSS3-capable browser would be required to see the HTML rendition.

slash-radius-fig1

The slash-based syntax might be a difficult thing to wrap your mind around, so let’s examine how the syntax relates to what’s happening to the shape of the corners on that element.

slash-radius-fig2

In the above image, I’ve blown up the element and placed an ellipse into the corner so that the upper curve of the ellipse overlaps the rounded corner as closely as possible. A “radius”, according to the dictionary definition is “a straight line extending from the center of a circle or sphere to the circumference or surface.”

According to the spec, the values you give the border-radius property “define the radii of a quarter ellipse that defines the shape of the corner of the outer border edge.” Thus, if you add the full ellipse (as I’ve done above), you’ll see exactly how the radii are calculated. In the image, I’ve drawn arrows indicating the horizontal and vertical radii (marked with “H” and “V”).

Keep in mind that because of pixelation (in the original and the blown up version), this can’t be an exact science; that would be something more appropriate when dealing with vector-based shapes.

Other Horizontal/Vertical Radii Options

Of course, the slash-based syntax is not just limited to two values; if you wish, you can set specific vertical and horizontal radius values for each corner of the element.

The syntax from above can alternatively be expressed like this:

#element {

  border-radius: 55px 55px 55px 55px / 25px 25px 25px 25px;

}

The values before the slash represent the horizontal radii for the top-left, top-right, bottom-right, and bottom-left corners, respectively. The values after the slash represent the vertical radii for those same corners, in that order.

And of course, similar to the traditional syntax, you can omit one or two values from before or after the slash, and the missing values will inherit from the existing ones.

You also have the option to declare different vertical and horizontal radii using the longhand syntax for each corner. So if we wanted to use longhand syntax to create the same shape from above, we would do this:

#element {

  border-top-left-radius: 55px 25px;

  border-top-right-radius: 55px 25px;

  border-bottom-right-radius: 55px 25px;

  border-bottom-left-radius: 55px 25px;

}

Notice that this time there is no slash used. In this case, the two space-separated values on each line represent the horizontal and vertical radii, respectively, for the given corner.

When Should This Syntax Be Used?

It should be noted that this syntax to target vertical and horizontal radius values for each corner would only be used if you want the vertical and horizontal radius values on a single corner to differ from one another. That means you would not need to use this syntax if you want equal horizontal and vertical radius values for each corner.

Significantly, you could also employ this syntax when changing radius values via scripting. Thus, when used appropriately, this could open the door for some interesting animations using transitions or keyframe-based animations.

So in most—if not all—cases, you can stick to the traditional syntax, and only use the syntax described here if you want one or more nonsymmetrical rounded corners.

Even so, this information should be enough for you to want to experiment a little further with this otherwise well-known CSS3 property.

Let me know what you come up with.

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • Russ

    Nice work, didn’t know about the slash syntax either. Now watch some smartypants folks mess about and see what happens in different browsers when a slash is used and nothing follows it – what defaults occur then? (A waste of time? Possibly, but look at what Tantek et al did with existing CSS1/2 syntaxes to solve complex problems back in the day).

    Cheers!

  • mOrloff

    As usual, I loved today’s (04/26/11) newsletter.
    I tried a combination of TWO of the concepts from that issue:
    1. Paper Curl
    2. Slash syntax Border-Radius.
    It came out AWESOME.
    Thanks-a-bunch!

    Here’s the sample code:
    [CODE]
    body {background:#EEEEEE;}
    #test1 {
    position: relative;
    background:#446688;
    margin: auto;
    width: 75%;
    height: 75%;
    border-radius: 50px 50px 75px 75px / 1px 1px 2px 2px;
    -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2),
    inset 0 0 50px rgba(0, 0, 0, 0.1);
    -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.2),
    inset 0 0 50px rgba(0, 0, 0, 0.1);
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2),
    inset 0 0 50px rgba(0, 0, 0, 0.1);
    }
    #test1:before, #test1:after{
    position: absolute;
    width: 40%;
    height: 10px;
    content: ‘ ‘;
    left: 2px;
    bottom: 12px;
    background: transparent;
    -webkit-transform: skew(-7deg) rotate(-7deg);
    -moz-transform: rotate(-7deg);
    -ms-transform: skew(-7deg) rotate(-7deg);
    -o-transform: skew(-7deg) rotate(-7deg);
    transform: skew(-7deg) rotate(-7deg);
    -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
    -moz-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
    z-index: -1;
    }
    #test1:after{
    left: auto;
    right: 2px;
    -webkit-transform: skew(7deg) rotate(7deg);
    -moz-transform: skew(7deg) rotate(7deg);
    -ms-transform: skew(7deg) rotate(7deg);
    -o-transform: skew(7deg) rotate(7deg);
    transform: skew(7deg) rotate(7deg);
    }

    [/CODE]

    • Bill

      well done – zurb has a few writeups combining patterns as well it think … good summary on the ‘/’ tho – cuz i’d not heard of that one yet :)

  • Aaron

    That is awesome! Thanks dude for the info!

  • http://www.brothercake.com/ James Edwards

    It’s best not to use this syntax — for now — because the webkit and early moz vendor implementations don’t support it. You’ll end up having to define the border-radius in different ways for different implementations, which could quickly get confusing.

    Until we’re shot of all those, it’s much better to define individual longhand radii when you need complex corners — that way you can just copy and paste it for each vendor implementation.

  • Louis Lazaris

    Hey, James, thanks for the input.

    From my testing, it works on Chrome 10+, Firefox 3.5+ (with -moz-), and Safari 5+.

    So the only areas of concern are FF 3.0 (non-existent), Safari 4, and possibly earlier Chrome (I couldn’t test earlier versions of Chrome at the moment).

    Those problem areas are pretty scarce right now, so I don’t think it’s all that bad to use this syntax, as long as you test what the degraded experience looks like. After all, this is just decorative and is not crucial.

    • http://www.brothercake.com/ James Edwards

      Yeah it’s early -webkit implementations that will miss out. But as you say, it doesn’t really matter.

  • DirTek

    Very useful article!

    I’ve been exploring CSS3 for a long time but this is something new for me.

    Thanks for the great article!

  • LuciferX

    Awesome !
    I like this very good article ^^

  • Christian Krammer

    A very detailed article. If you are interested in this topic maybe you also want to check out the in-depth explanation at http://www.css3files.com/border.