codr.tools
Tools

Border-radius generator

Build a CSS border-radius visually: one radius per corner or the elliptical slash syntax for organic blob shapes, with presets, a live preview, the shortest correct shorthand and the corner longhands.

Corners

Radius mode
Presets

The slider covers 0 to 400px. Type a larger number in the field for a pill.

One radius per corner. Advanced mode splits every corner into a horizontal and a vertical radius, which is what bends a box into a blob.

Preview

Nothing overlaps at this size, so the browser draws the radii as written.

Generated CSS

border-radius: 16px;
Also show

Paste a border-radius value to put it back on the sliders. One unit at a time, and a bare 0 fits any of them.

Build a CSS border-radius visually: one radius per corner or the elliptical slash syntax for organic blob shapes, with presets, a live preview, the shortest correct shorthand and the corner longhands.

How to use this tool#

  1. Start in Simple mode. With "Link all corners" on, one slider rounds the whole box. Turn it off to set each corner on its own.
  2. Pick a unit. px is a fixed length, % is measured against the box, and rem and em follow a font size. The unit applies to every corner at once.
  3. Switch to Advanced for blobs. Each corner splits into a horizontal and a vertical radius, the / syntax. That is the only way to get an organic shape out of border-radius.
  4. Try the presets, or press Random blob until something looks right. A preset that needs the elliptical form switches the tool to Advanced for you.
  5. Set the preview box. Width and height matter: a percentage radius is measured against them, and so is the scaling that turns a huge radius into a pill.
  6. Copy the CSS. The output is the shortest shorthand that means exactly what the sliders say. Tick "Corner longhands" if you would rather have the four separate properties.
  7. Already have a value? Paste it into "Load a value you already have" and the sliders will take its shape.

Nothing is uploaded. The shape is computed in your browser and the page keeps no copy of it.

What border-radius does#

border-radius rounds the corners of a box. Each corner is drawn as a quarter of an ellipse, and the property sets that ellipse's two radii: one measured along the top or bottom edge, one measured down the left or right edge. When both are equal the corner is a quarter circle, which is the rounding everybody reaches for. When they differ the corner stretches, and that is where blobs, leaves and ticket edges come from.

It is defined in CSS Backgrounds and Borders Level 3, section 4.1. The radius shapes the outer border edge, so it affects the border, the background and, when overflow is clipped, everything inside the box. It applies whether or not the element has a border at all.

Two rules are worth having in your head before anything else:

  • Negative values are invalid. The spec says so in as many words.
  • A radius can be a length, a percentage or a calc(), and a plain0 needs no unit, the same as anywhere else in CSS.

The shorthand order: top-left, top-right, bottom-right, bottom-left#

border-radius takes one to four values, and they go clockwise from the top-left corner. That is a different order from margin and padding, which start at the top edge, so the two are easy to confuse.

The omission rules, straight from the spec:

  • If bottom-left is omitted it is the same as top-right.
  • If bottom-right is omitted it is the same as top-left.
  • If top-right is omitted it is the same as top-left.

Applied in that order, one to four values expand like this:

css
/* One value: every corner */
border-radius: 12px;

/* Two: top-left & bottom-right, then top-right & bottom-left */
border-radius: 12px 0;

/* Three: top-left, then top-right & bottom-left, then bottom-right */
border-radius: 12px 0 4px;

/* Four: top-left, top-right, bottom-right, bottom-left. Clockwise. */
border-radius: 12px 0 4px 24px;

Read backwards, those rules are also the collapsing rules, which is what this tool does to keep the output short. Four equal corners become one value. Matching diagonals become two. If only top-right and bottom-left match, three values are enough. Otherwise you need all four.

The slash: elliptical corners#

Put a / in the value and you get eight numbers instead of four. The spec is precise about which is which: "the values before the slash set the horizontal radii and the values after the slash set the vertical radii. If there is no slash, then the values set the radii in both axes equally."

Each side of the slash takes one to four values and expands with exactly the same omission rules as above, independently of the other side.

css
/* Every corner: 40px across, 20px down */
border-radius: 40px / 20px;

/* The same thing written out in full */
border-radius: 40px 40px 40px 40px / 20px 20px 20px 20px;

/* Each side of the slash expands on its own */
border-radius: 10px 40px / 20px;
/* horizontal: 10px 40px 10px 40px
   vertical:   20px 20px 20px 20px */

This is the whole trick behind CSS "blobs". A blob is not a special shape or a hidden feature: it is eight percentages, chosen so that no edge of the box is left straight.

css
.blob {
  width: 320px;
  height: 240px;
  border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}

/* Each edge's two radii add up to 100%, so the outline curves
   from end to end with no straight run left anywhere. */

The Random blob button above picks its numbers so that the two radii on each edge add up to 100%. That is what removes every flat segment and keeps the outline smooth all the way round. Animate between two such values and you get the slow-morphing blob you have seen on landing pages; border-radius is interpolable, so a plain transition handles it.

What percentages are measured against#

The spec sentence is short and worth memorising:

So border-radius: 50% is not "half of something". It is half the width on one axis and half the height on the other, which draws an ellipse inscribed exactly in the box. On a square box that ellipse is a circle, which is why 50% is the standard way to round an avatar.

The border box includes the border, so a border width changes what a percentage resolves to. It also means a percentage radius is alive: resize the element and the corner resizes with it. That is a feature on a fluid card and a nuisance on a button, where a fixed px value keeps the corner the same whatever the label says. The preview above has width and height sliders for precisely this reason.

When radii overlap, the browser scales them down#

Nothing stops you asking for two radii that together are longer than the edge they sit on. The browser does not clip them or reject the value. It shrinks all of them, proportionally, until they fit. Section 4.5 of the spec, "Overlapping Curves", gives the algorithm:

In plain terms:

  • The top and bottom edges are measured against the horizontal radii and the box width. The left and right edges are measured against the vertical radii and the box height.
  • The worst-fitting edge decides. Its ratio becomes f, and every radius on the box is multiplied by it, including the ones that fitted perfectly well.
  • Scaling only ever shrinks. If every edge has room, f is 1 and nothing changes.

That single rule explains the two shapes everybody wants. The preview above reports f whenever it drops below 1.

css
/* A pill: the radius is far bigger than the box, so it is scaled
   down to exactly half the shorter side. */
.pill {
  height: 40px;
  border-radius: 9999px;
}

/* An ellipse inscribed in the box, whatever its size. */
.ellipse {
  border-radius: 50%;
}

/* A circle only if the box is square. */
.avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
}

Why 9999px makes a pill. On a 40px-tall button the left edge alone is asked for 19998px of radius on 40px of edge, so f is about 0.002 and every radius lands at 20px: exactly half the height, a semicircle at each end. Any number big enough to trigger the scaling gives the same result, so 9999px is just a conventional "big enough for anything".

Why 50% makes an ellipse. Each edge is asked for 50% + 50% = 100% of its own length, so f is exactly 1. No scaling happens; the four quarter-ellipses simply meet at the middle of every edge, leaving no straight segment at all.

The two are not interchangeable. 50% on a wide button gives you a flattened ellipse, not a pill, because the corner keeps following the box's proportions. A large px value gives a true stadium shape at any width.

The spec attaches a warning to this rule that is easy to hit in practice: because fapplies to every corner, "this may make borders of nearby elements that should look the same look different". Two cards with the same border-radius can end up with visibly different corners if one of them is short enough to trigger the scaling.

The four corner longhands#

The shorthand sets four longhand properties: border-top-left-radius, border-top-right-radius, border-bottom-right-radius and border-bottom-left-radius. Each takes one or two values: the horizontal radius, then the vertical one. "If the second value is omitted it is copied from the first."

Reach for a longhand when you want to change one corner without restating the other three, which is common in component CSS: a shared card class rounds everything, and a modifier squares off the corner where the card meets something else. Tick "Corner longhands" above to see them for the shape on screen.

Logical corners: border-start-start-radius and friends#

The four properties above are physical. They name corners of the screen, so they do not follow the text when the writing mode or the direction changes. CSS Logical Properties Level 1 adds flow-relative versions: border-start-start-radius, border-start-end-radius, border-end-start-radius and border-end-end-radius.

The first half of the name is the block axis, the second is the inline axis. In the common case,writing-mode: horizontal-tb with direction: ltr, they map to the physical corners like this:

  • border-start-start-radius is the top-left corner.
  • border-start-end-radius is the top-right corner.
  • border-end-end-radius is the bottom-right corner.
  • border-end-start-radius is the bottom-left corner.

Switch the page to direction: rtl and the inline axis mirrors, so start-start becomes the top-right corner. In writing-mode: vertical-rl the block axis runs right to left and start-start is the top-right corner again. That is the point: a speech bubble whose square corner marks its speaker stays correct in Arabic or Hebrew without a second rule.

css
/* Physical: always the top-left corner of the screen. */
border-top-left-radius: 12px;

/* Flow-relative: the corner where the block and inline axes start.
   In horizontal-tb + ltr that is the top-left. In rtl it is the
   top-right, and the layout mirrors with the text. */
border-start-start-radius: 12px;
border-start-end-radius: 12px;
border-end-end-radius: 0;
border-end-start-radius: 0;

Two practical notes. There is no logical shorthand: nothing writes all four flow-relative corners in one declaration, so you set them one at a time. And support is not a problem any more; MDN lists these properties as widely available across browsers since September 2021. Tick "Logical properties" above to get the longhands in this form.

Radius, borders, overflow, outlines and shadows#

The inner curve of a border

A border does not keep a constant radius on both of its edges. The spec: "The padding edge (inner border) radius is the outer border radius minus the corresponding border thickness. In the case where this results in a negative value, the inner radius is zero."

So a 12px radius with a 4px border curves at 8px on the inside. And a border thicker than the radius leaves a square inner corner against a rounded outer one, which looks like a mistake and usually is one. The same subtraction is how you nest two rounded boxes without the gap between them looking uneven: the inner radius should be the outer radius minus the padding.

Overflow

Rounding a parent does not round its children. Section 4.3 of the spec lists what does follow the curve: "overflow values other than visible" clip "to the curved padding edge", replaced content such as an <img> clips to the curved content edge, and backgrounds clip to whichever curve background-clip names.

The practical consequence: a rounded card holding an image at the top needs overflow: hidden on the card, or the image's square corners paint straight over the rounding. Setting a radius on the image itself works too, but then you have two numbers to keep in step.

css
/* Without this, a square child paints straight over the
   rounded corner of its parent. */
.card {
  border-radius: 12px;
  overflow: hidden;
}

/* A border makes the inner curve tighter: 12px - 4px = 8px. */
.framed {
  border: 4px solid #15191e;
  border-radius: 12px;
}

/* Nesting: keep the gap constant by subtracting the padding. */
.outer { border-radius: 16px; padding: 8px; }
.inner { border-radius: 8px; }

Shadows

box-shadow needs nothing extra. An outer shadow "casts a shadow as if the border-box of the element were opaque", and that border box is the rounded one, so the shadow follows the corners on its own. Our box-shadow generator builds the other half of that pair.

Outlines

outline is the one to check rather than assume. CSS Basic User Interface Level 4 says an outline "should follow the border-radius curve, as well as the corner-shape". That is a recommendation, not a requirement, and browsers did not always honour it: rectangular focus rings around rounded buttons were normal for years. Current engines do round the outline, but if the focus ring on a very round control matters to your design, look at it rather than trusting it.

Pointer events

The cut-off corner really is cut off. The same section says pointer events clip "to the curved border edge", and the spec adds a note: "As border-radius reduces the interactive area of an element authors should make sure the remaining interactive area conforms to recommended minima for the platforms they target." A heavily rounded icon button loses real estate at every corner, so keep the tappable area honest.

Worked examples#

css
.ticket {
  /* Wide, shallow corners: the die-cut look of a printed ticket. */
  border-radius: 28px / 14px;
}

.tab {
  /* Rounded on top, square where it meets the panel. */
  border-radius: 8px 8px 0 0;
}

.bubble {
  /* One corner pulled in, so the bubble points at its speaker. */
  border-radius: 20px 20px 20px 4px;
}

.leaf {
  border-radius: 0 50%;
}

All four are in the preset row above, so you can drop one in and adjust it rather than starting from zero. The ticket is the interesting one: 28px / 14px gives a corner that is twice as wide as it is deep, which reads as a die-cut edge rather than a soft rounding.

Questions people ask#

What order do the four values go in?

Top-left, top-right, bottom-right, bottom-left. Clockwise from the top-left. It is not the same order as margin or padding, which start at the top edge and go clockwise from there. If you only remember one thing, remember that border-radius counts corners, not edges.

How do I make a circle?

border-radius: 50% on a box whose width and height are equal. If the box is not square, 50% gives you an ellipse that fills it. To get a circle from a non-square element you have to make it square first, with aspect-ratio: 1 or matching width and height.

What is the difference between 50% and 9999px?

50% follows the box's proportions and produces an ellipse. 9999px is scaled down by the overlap rule to half the shorter side and produces a pill with genuinely semicircular ends. On a square box the two look identical. On a wide, short box they are clearly different, and the pill is almost always the one you wanted.

How do I make a blob?

Use the elliptical form with eight percentages, for example border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%. Switch this tool to Advanced and press Random blob to get one, or drag the eight sliders yourself. Keep the two values on each edge adding up to 100% and the outline stays smooth.

Can I cut a notch into a corner instead of rounding it?

Not with border-radius. Every corner it draws is a quarter ellipse bulging outwards, and negative values are invalid, so there is no way to make it curve inwards. Inward notches, the kind a cinema ticket has, need clip-path, a mask, or a pair of overlapping circles drawn with pseudo-elements. The Ticket preset here is the flatter, die-cut corner that border-radius can actually produce.

Why is my radius not showing up?

Three usual causes, in order of how often they turn out to be the answer:

  • A child element is painting over it. Add overflow: hidden to the rounded parent.
  • The element is a <table> with border-collapse: collapse. The spec is explicit: in that mode the radius properties "have no effect". Use border-collapse: separate.
  • The radius is there but the overlap rule shrank it, because the box is shorter or narrower than you thought. Drag the height slider above to see that happen.

Can border-radius be animated?

Yes. The corner radii interpolate as lengths and percentages, so transition and@keyframes both work. Morphing between two blob values is the usual use, and it is cheap enough as long as you are not animating it on a hundred elements at once. Pair it with ourcubic-bezier generator if the default easing feels wrong.

Should I use px, rem or percentages?

px for controls and small components, where the corner should stay the same whatever the content does. rem when you want the rounding to scale with the user's font size, which is the honest choice on a typographic layout. % when the shape itself should follow the box: avatars, pills on fluid elements, and every blob. Mixing units across corners is legal CSS; this tool keeps to one at a time because one is nearly always what you want.

Does any of this get sent anywhere?

No. The sliders, the preview and the generated CSS all run in your browser. The site is static files with no backend, so there is nowhere for the shape to go. Turn off your network and the tool keeps working.

  • Build a CSS box-shadow visually, with as many layers as you need: offsets, blur, spread, colour with opacity and inset, over a preview whose box colour, background and border radius you set yourself.

  • Build linear, radial and conic CSS gradients visually: any angle, shape, size and centre, colour stops with their own position and opacity, repeating variants and an interpolation colour space, with the background declaration ready to copy.

  • Draw a CSS easing curve by dragging its two control points, compare it against linear in a live preview, start from the keyword and named presets, and copy the cubic-bezier() value or a ready transition line.

  • Work out a fluid clamp() declaration from a size at two viewport widths, with the slope and intercept shown, a live preview at any width, a type scale in custom properties and a check that the text still resizes.