Sebastin Santy
Sebastin Santy

Reputation: 1152

Avoid elliptical shape in CSS border-radius

Using Border-radius CSS for rectangular divs produces elliptical corners instead of rounded corners. How can I get perfect rounded corners for rectangular divs?

Upvotes: 68

Views: 62579

Answers (8)

Woodrow Barlow
Woodrow Barlow

Reputation: 9087

image from MDN
(source: mozilla.org)

Formally, the syntax for the border-radius property accepts 2 values for each corner: a horizontal radius and a vertical radius (separated by a slash). The following line would create an elliptical border-radius similar to the third image above.

border-radius: 10px / 5px;

Usually, we only specify one value. In this case, that value gets used as both the vertical and horizontal radii. The following line would create a circular border-radius similar to the second image above.

border-radius: 10px;

Using Percentages

The Mozilla Developer's Network defines the possible value types for this property as follows:

<length>
Denotes the size of the circle radius or the semi-major and semi-minor axes of the ellipsis. It can be expressed in any unit allowed by the CSS data types. Negative values are invalid.

<percentage>
Denotes the size of the circle radius, or the semi-major and semi-minor axes of the ellipsis, using percentage values. Percentages for the horizontal axis refer to the width of the box, percentages for the vertical axis refer to the height of the box. Negative values are invalid.

Using a single value to create a circular radius is fine when we're using absolute length units like pixels or ems, but gets more complicated when we're using percentages. Since the single-value usage of this property is synonymous with using the same value twice, the following two lines are equivalent; however, these would not necessarily create a circular border-radius.

border-radius: 50%;
border-radius: 50%/50%;

These lines say the border is defined by an ellipse whose vertical radius is equal to 50% of the element's height and whose horizontal radius is equal to 50% of the element's width. If the element is 200 pixels wide and 100 pixels tall, this results in an ellipse rather than a circle.


Solution

If you want a circular border-radius, the easiest thing to do is to use absolute measurement units (like pixels or ems or anything besides percentage), but sometimes that doesn't fit your use case and you want to use percentages. If you know the aspect-ratio of the containing element, you still can! In the example below, since my element is twice as wide as it is tall, I've scaled the horizontal radius in half.

#rect {
  width: 200px;
  height: 100px;
  background: #000;
  border-radius: 25%/50%;
}
<div id="rect"></div>

Another option is to provide a sufficiently huge value in any absolute measurement unit. If the value exceeds half of the shortest side's length, the browser will use the minimum as its border-radius in both directions, producing a perfect pill shape on rectangular elements.

#rect {
  width: 200px;
  height: 100px;
  background: #000;
  border-radius: 100vmax;
}
<div id="rect"></div>

Upvotes: 81

mohiwalla
mohiwalla

Reputation: 51

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 50px;
            border: 1px solid black;
            aspect-ratio: 1;
            resize: both;
            overflow: auto;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <script>
        const ro = new ResizeObserver(entries => {
            for (let entry of entries) {
                entry.target.style.borderRadius = entry.target.style.width;
            }
        });
        ro.observe(document.querySelector('.box'));
    </script>
</body>

</html>

Upvotes: 1

Donny Phan
Donny Phan

Reputation: 41

adding to Kelvin's answer, to get perfectly round corners on a rectangle, try:

button {
    border-radius: 50vh;
}

Upvotes: 4

wyvern
wyvern

Reputation: 136

Just define the radius using vw/vh (worked for me at least):

button{
    border-radius:1vh;
}

This works as vh / vw are always constant to the viewport and independant of the element :)

Upvotes: 4

manzim
manzim

Reputation: 29

style={{ 
        height: "150px", 
        width: "150px", 
        borderRadius: "50%", 
        boxSizing: "border-box", 
        overflow: "hidden"                         
}}

This is what that relieved me from annoying OVAL Shape problem.

  • this is inline CSS.

Upvotes: 0

user208769
user208769

Reputation: 2226

Another thing that affects the border radius is, ironically, border.... if you have a border-top and no border on the sides, you'll see the same lopsided border rounding effect as you get when you use percentage-based radius.

I can see this being a useful feature. But please, please, put a comment in your CSS to tell future-you (or others) why you're doing it. Debugging this was painful!

Upvotes: 2

Borsunho
Borsunho

Reputation: 1167

border-radius: 9999px does produce 'perfect 1/4 circle' corners, that's why you can make css circles with this property. They sometimes don't look like they are perfectly round corners, but that's an optical illusion. If this bothers you, you can try to imitate the effect with something like border-radius: 9px / 8px

border-radius: 50% will, on the other hand, produce non-circular arcs if your div is not square. Again, you can override behavior you don't like by specifying separate radii for x and y axis like border-radius: 10% / 20%.

Upvotes: 18

Kyle
Kyle

Reputation: 1503

If you're using a percent it can cause that stretching/elliptical appearance. You may want to try designating the units in px for more of a customized rounded look.

Upvotes: 5

Related Questions