Reputation: 103750
If I use a pixel or em value for border-radius, the edge radius is always a circular arc or a pill shape even if the value is greater than the largest side of the element.
When I use percentages, the edge radius is elliptic and starts at the middle of each side of the element resulting in an oval or ellipse shape :
Pixel value for border-radius :
div {
background: teal;
border-radius: 999px;
width: 230px;
height: 100px;
padding: 40px 10px;
box-sizing: border-box;
font-family: courier;
color: #fff;
}
<div>border-radius:999px;</div>
Percent value for border-radius :
div {
background: teal;
border-radius: 50%;
width: 230px;
height: 100px;
padding:40px 10px;
box-sizing:border-box;
font-family:courier;
color:#fff;
}
<div>border-radius:50%;</div>
Why doesn't border radius in percentages act the same way as border-radius set with pixel or em values?
Upvotes: 207
Views: 121381
Reputation: 1
Upvotes: 0
Reputation: 103750
First, you need to understand that the border-radius property takes 2 values. These values are the radii on the X/Y axis of a quarter ellipse defining the shape of the corner.
If only one of the values is set then the second value is equal to the first one.
So border-radius: x;
is equivalent to border-radius: x/x;
.
Referring to the W3C specs : CSS Backgrounds and Borders Module Level 3 border-radius property this is what we can read concerning percentage values:
Percentages: Refer to corresponding dimension of the border box.
So border-radius: 50%;
defines the radii of the ellipse this way :
Using one value other than a percentage for border radius (em, in, viewport related units, cm...) will always result in an ellipse with the same X/Y radii. In other words, a circle.
When you set border-radius: 999px;
the radii of the circle should be 999px. But another rule is applied when the curves overlap reducing the radii of the circle to half the size of the smallest side. So in your example it is equal to half the height of the element : 50px.
For this example (with a fixed size element) you can obtain the same result with both px and percentages. As the element is 230px x 100px
, border-radius: 50%;
is equivalent to border-radius: 115px/50px;
(50% of both sides) :
.percent {
border-radius: 50%;
}
.pixels {
border-radius: 115px/50px;
}
/* For the demo : */
div {
display: inline-block;
background: teal;
width: 230px;
height: 100px;
padding: 40px 10px;
box-sizing: border-box;
font-family: courier;
font-size: 0.8em;
color: #fff;
text-align: center;
}
<div class="percent">border-radius: 50%;</div>
<div class="pixels">border-radius: 115px/50px;</div>
Upvotes: 310
Reputation: 141
a way to get it properly scaling to the viewport size, but staying rounded without any js, would be to do:
border-radius: 3vmin;
then it will always scale to the smallest dimension, so you will never have a box with semicircular sides, and you don't need any js to calculate the correct percentages.
edit: sorry, forgot vmin
existed, so changed it to use that instead.
Upvotes: 10
Reputation: 1124
Just divide the first value by the % you want.. so if you want a border-radius of 50%, write:
border-radius: 25%/50%;
or another example:
border-radius: 15%/30%;
You can easily do the math in js or SASS.
Upvotes: 4