CSS Circle Generator

The simplest shape, and the one with two answers. Generate it as a clip-path circle, and read below for when border-radius is the better tool.

About the CSS circle

The circle is the one shape CSS has always been able to draw, and it is the one where the interesting question is not how but which. There are two ways to make an element round, they look identical, and they behave completely differently the moment you add a border, a shadow or something that overflows.

The code

.shape {
  aspect-ratio: 1 / 1;
  clip-path: circle(50% at 50% 50%);
  width: 240px;
  background: #0d6efd;
}

circle() takes a radius and a centre. 50% of what, though, is the part that surprises people: a percentage radius is resolved against the diagonal of the box - specifically √(w² + h²) / √2 - not against its width. In a square box that works out to exactly half the width, which is why the aspect ratio is worth keeping. In a rectangle, circle(50%) is still a perfect circle, just a larger one than you probably expected, with its edges cut off by the box.

The keywords are easier to reason about: circle(closest-side) fits the circle inside the box, circle(farthest-side) makes it big enough to reach the longest edge. And the centre can be anything a background position can: circle(50% at top left) gives you a quarter circle in the corner.

clip-path or border-radius?

border-radius: 50% does the same visual job in fewer characters, and for most avatars it is the right answer. The difference is what the element still has afterwards:

  • Borders - border-radius keeps them and bends them round the curve. clip-path clips the border away with everything else, so a clipped circle cannot have one.
  • Shadows - box-shadow follows a rounded corner. It does not survive a clip; you need filter: drop-shadow() on a parent instead.
  • Overflow - a rounded box only clips its children if you also say overflow: hidden. A clip-path always clips them, which is exactly what you want for a photo and a nuisance for a tooltip that needs to escape.
  • Partial circles - clip-path can put the centre anywhere and make quarter and half circles trivially. border-radius needs a corner at a time.
  • Animation - both animate, but clip-path: circle() is the standard way to do a circular reveal growing from a point.

The short version: reach for border-radius by default, and for clip-path when you need the circle to cut something - a reveal, a mask over a video, a circle that is not centred.

Frequently asked questions

Why is my circle an oval?

With border-radius: 50%, because the box is not square - the radius is 50% of each side separately, so a wide box gives an ellipse. With clip-path: circle() it never becomes an oval; instead the circle stays round and the box crops it. Either way, the fix is aspect-ratio: 1 / 1.

How do I make a circular avatar from a photo?

border-radius: 50% plus object-fit: cover on the <img>, with a square aspect ratio. That gives you a round photo that can still take a border ring, which avatars usually want. Use clip-path instead only if you need a shape other than a plain circle.

Can I make a ring or a donut?

Not with a single circle() - a clip-path has no hole. A ring is easiest as a border: a square element with border-radius: 50%, a thick border and no background. For a ring with a gradient, stack two circles or use an SVG with a stroked circle.

What is the difference between circle() and ellipse()?

circle() takes one radius, ellipse() takes two - horizontal and vertical - so an ellipse can be as flat or as tall as you like without touching the box. If you want an oval in a square box, that is the function to use. There are half and quarter circle presets too.

More CSS shapes