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 source | In your browser | Proper rendering |
---|---|---|
width: 48px; height: 48px; border: 1px solid black; border-radius: 10px; |
||
border-radius: 10px 0px; |
||
border-radius: 10px 0px 20px; |
||
border-radius: 10px 0px 20px 30px; |
||
border-top-left-radius: 20px 30px; |
||
border-radius: 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 thickness | Varying thickness | Sharp 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 source | In your browser | Proper rendering |
---|---|---|
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.
Transitions
Color and style transitions |
In your browser | Ideal rendering |
---|---|---|
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 browser | Ideal rendering |
---|---|---|
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
Clipping | In your browser | Proper rendering |
---|---|---|
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 | |||||||
---|---|---|---|---|---|---|---|---|---|
Firefox 3.5 | Firefox 3.0 |
Current (Epiphany 2.27.3, using Webkit 1.1.10) |
Older (Safari 3.2.2 for Windows) |
Opera (9, 10) |
IE (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 | |||||