Boxes with Rounded Corners

The CSS 3 Backgrounds and Borders module introduces the border-radius property, which allows you to make the border of any CSS box be a rounded rectangle. Mozilla’s Gecko-based browsers (such as Firefox and SeaMonkey) have implemented parts of this feature for some time, as have Webkit-based browsers (such as Safari and Chrome). Firefox 3.5 adds support for elliptical corners, and brings the Gecko implementation into line with the standard on many details.

At the time of writing, the Backgrounds and Borders module is still a W3C Working Draft, so all the browsers that implement border-radius require you to use vendor-prefixed property names for it. This article uses the standard property names in all examples, but there is a table of equivalences at the end. Mozilla’s policy is to enable the standard names once the module reaches Candidate Recommendation stage; see bug 451134.

Introduction to rounded corners

CSS sourceIn your
width: 48px; height: 48px;
border: 1px solid black;
border-radius: 10px;
border-radius: 10px  0px;
border-radius: 10px  0px
border-radius: 10px  0px
               20px 30px;
    20px 30px;
    10px 0 / 30px 0;
border-radius: 10px /
    30px 30px 10px 10px;

In its simplest form, border-radius takes a single CSS <length> and rounds all four corners of a box border by that amount. Rounded corners are never inherited by descendant boxes.

If you want the corners to have different sizes, you can list up to four <length>s; these round individual corners, counting clockwise from the top left. With two or three numbers, the missing values default to the value for the diagonally opposite corner.

You can also use longhand properties to control the curvature of each corner independently from the others: border-top-left-radius, border-top-right-radius, border-bottom-right-radius, and border-bottom-left-radius. Each takes a single <length>. There is no defaulting from one corner to another with these properties.

The Backgrounds module adds the possibility of elliptical corners. If you’re using the longhand properties, you simply add a second <length> value to the property; the first value sets the horizontal semi-axis of the ellipse, the second sets the vertical semi-axis. With the shorthand border-radius property, the notation is slightly more involved: after the first list of up to four <length>s, you add a forward slash and another list of up to four <length>s. The values before the slash set the horizontal semi-axes, and the values after set the vertical semi-axes; both go clockwise from top left, and default independently to diagonally opposite corners. If either semi-axis of a corner is zero, that corner will not be rounded.

Webkit does not treat border-radius as a shorthand property; it accepts only one <length> value. If you want any effect other than setting all four corners to the same circular radius, you must use the longhand properties with Webkit. See bug 23675.

Corner styling in detail

Constant thicknessVarying thicknessSharp inner corner

The border-radius properties directly control the horizontal and vertical semi-axes of the outer curve of the border. The inner curve is determined by reducing each semi-axis by the thickness of the side border adjacent to that end of the curve. This keeps the curved portion of the border within a rectangle whose sides are the semi-axes set by border-radius.

Inner curve kink effect
border: 6px solid black;
border-radius: 8px / 20px;
border-style: double;

When both sides’ borders are the same thickness, the curve has constant thickness; when they are not the same, the curved portion of the border interpolates smoothly between the two. When the border is at least as thick as the border-radius value on at least one side, the inner curve becomes a sharp corner. Thick elliptical borders sometimes look kinked because the inner curve is very flat.

CSS sourceIn your
width: 48px; height: 48px;
border: 1px solid black;
border-radius: 25px 0;
border-radius: 40px 0;
border-radius: 50px 0;
border-radius: 40px 10px
               10px 10px;
border-radius: 50px 10px
               10px 10px;
border-radius:100px 10px
               10px 10px;

When the curves are too big for the box, something has to give. The Backgrounds module constrains the sum of the semi-axes on each side of the box to be no more than the outer dimension of the border box on that side; thus you can make one corner curve all the way to the opposite side of the box, as long as both corners adjacent to it are not curved at all. When the sum is too big on even one side, the renderer is required to compute a reduction factor that will make the largest pair of semi-axes fit exactly within the box, and apply that reduction to all the semi-axes. This has advantages and disadvantages; in the spec’s words,

This [rule] ensures that quarter circles remain quarter circles and large [corners] remain larger than smaller ones, but it may reduce corners that were already small enough, which may make borders of nearby elements that should look the same look different.

At time of writing, this rule is implemented in full only by Firefox 3.5 and very recent versions of Webkit (library version 1.1.8 and later; see bug 8736). Older Gecko-based browsers scale each arc independently, and limit each corner to half the outer dimensions of the border box. Older Webkit-based browsers ignore all the corner radii for a box if the sum of the semi-axes on any side is greater than the outer dimension of the border box on that side.


Color and style
In your
border-radius: 20px;
border: 4px solid;
border-color: red green
              blue gray;
border: 6px black;
border-style: solid  solid
             double double;

The Backgrounds module leaves the visual appearance of a transition between border colors and/or border styles undefined, but does require that they take place entirely within the curved region of the border. It does, however, recommend the use of a gradient for transitions involving color only.

Both Gecko- and Webkit-based browsers currently implement all such transitions as abrupt, occurring at the diagonal of the rectangle that encloses the corner curve. This may change in the future, at least for color transitions; see bug 483696 for Gecko.

Borders that are not solid

Dotted and
dashed corners
In your
border-width: 2px;
border-radius: 15px;
border-style: dotted;
border-style: dashed;

In terms of what gets drawn on the screen, inset and outset borders are the same as solid borders that aren’t the same color all the way around, so they are also affected the same way by border-radius. Double, groove, and ridge borders are drawn with two or three stripes within the border thickness. The arc-reduction rule described above is applied to each stripe; this can exaggerate the apparent kink when the innermost arc is too flat, but otherwise works well.

For dotted and dashed borders, the dots or dashes are supposed to continue through the corner curve. Gecko-based browsers don’t implement this at all; the curved portions of the border are drawn as solid (bug 382721). Webkit draws dots and dashes along the curves, but may show artifacts at the ends of the curves.

Clipping of background and content

ClippingIn your
border-radius: 15px;
border: none;
overflow: visible;
overflow: hidden;

Both colored and image backgrounds are clipped to the curved border. This happens even if there is no visible border (with border-style: none, for instance). A border-image is not clipped, but backgrounds are still clipped to the curve, even though in the presence of border-image the regular border is not drawn.

Content is, by default, not clipped at all. If you use overflow:hidden, however, the Backgrounds module requires content to be clipped to the border curve. This works with very recent Webkit (partially, bug 9543) but not Gecko (bug 459144). or older versions of Webkit.

The spec says The UA may reduce or treat as zero the border-radius for a given corner if a scrolling mechanism is present in that corner. In other words, if there are scrollbars (overflow:scroll or overflow:auto), corners on the sides that actually have scrollbars may not be rounded. This is because the scrollbars themselves obviously should not be clipped, and the visual inconsistency was expected to be undesirable in at least some cases.

By default, the clipping path is the outer rounded rectangle; thus, the background will show under the border if the border is not fully opaque. (This is visible in several of the examples above.) The Backgrounds module includes a background-clip property that can change this. Gecko and Webkit both include partial support for this property, but they conform to an older revision of the spec: the value keywords are border and padding instead of border-box and padding-box; content-box and no-clip are not supported.

Browser compatibility matrix

Gecko-based Webkit-based Other
(Epiphany 2.27.3,
using Webkit 1.1.10)
(Safari 3.2.2
for Windows)
(9, 10)
(6, 7, 8)
Property Names
border-radius -moz-border-radius -webkit-border-radius Not supported Not supported
border-top-left-radius -moz-border-radius-topleft -webkit-border-top-left-radius
border-top-right-radius -moz-border-radius-topright -webkit-border-top-right-radius
border-bottom-right-radius -moz-border-radius-bottomright -webkit-border-bottom-right-radius
border-bottom-left-radius -moz-border-radius-bottomleft -webkit-border-bottom-left-radius
Value syntax
Single <length> Works Works Works Works
Two <length>s in longhand Works Not supported Works Works
More than one circular radius in shorthand Works Works Not supported Not supported
Elliptical curves in shorthand Works Not supported Not supported Not supported
Semantic details
Oversized radius reduction Works Buggy Works Buggy
Color transitions Abrupt Abrupt Abrupt Abrupt
Style transitions Abrupt Abrupt Abrupt Abrupt
Dotted and dashed corners Drawn solid Drawn solid Artifacts Artifacts
Background clipping Works Works Works Works
Overflow clipping Unimplemented Unimplemented Partial Unimplemented