EmpireUI
Get Pro
← Blog8 min read#border-radius#css#blob

CSS border-radius Patterns: From Rounded to Blob Shapes

Master CSS border-radius from simple pill buttons to organic blob shapes — with real code patterns, SVG tricks, and design system tips for modern UIs.

Abstract colorful rounded blob shapes on dark background

border-radius Is Not Just for Rounded Corners

Most developers stop at border-radius: 8px and call it a day. That's a shame. The property is way more powerful than that, and once you understand how it actually works — eight independent values, not one — you'll start seeing shapes everywhere that CSS can produce natively.

The full syntax is border-radius: <top-left> <top-right> <bottom-right> <bottom-left> / <top-left-vertical> <top-right-vertical> <bottom-right-vertical> <bottom-left-vertical>. That slash separates horizontal radii from vertical radii for each corner. Each corner is an ellipse, not a circle. So a single element can describe 8 independent curve values.

Worth noting: this has been fully supported since IE9 (2011), so there's zero reason to polyfill or avoid it. You're not doing anything experimental here.

Honestly, most UI frameworks treat border-radius as a simple token — sm, md, lg, full — and that discards 90% of the property's power. If you want to browse the components Empire UI builds for modern UIs, you'll notice shapes that go well beyond a standard 12px corner.

The Core Patterns Every Dev Should Know

Let's run through the patterns you'll actually reach for. Pill shape first — set border-radius: 9999px on any element and you get a pill regardless of dimensions. It works because the browser clips oversized radii to 50% of the shorter axis. Quick, predictable, no math needed.

Squircle is trickier. True squircles (the iOS icon shape) can't be done with border-radius alone — but you can get close with border-radius: 30% on a square. Not identical, but close enough for most design systems. If you need pixel-perfect squircles at, say, 48px × 48px for avatar thumbnails, reach for clip-path with a custom SVG polygon instead.

Asymmetric cards are where things get interesting. A border-radius: 24px 24px 80px 24px gives you one dramatically rounded corner, which is a common pattern in 2024–2026 brutalist-adjacent UI. Pair it with a solid 2px border and it reads clean.

Then there's the teardrop. Set border-radius: 50% 50% 50% 0 and you've got a map-pin shape pointing down-left. Rotate it 45deg and it points straight up. Useful for tooltips, pointers, and badge attachments without any SVG overhead.

/* Pill */
.pill { border-radius: 9999px; }

/* Soft squircle */
.squircle { border-radius: 30%; aspect-ratio: 1; }

/* Asymmetric card */
.card-accent {
  border-radius: 24px 24px 80px 24px;
  border: 2px solid currentColor;
}

/* Teardrop / map pin */
.pin {
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  width: 32px;
  height: 32px;
}

Building Organic Blob Shapes with Pure CSS

Blobs. Every design tool generates them, but shipping them as SVGs means static shapes that don't animate with CSS transitions. The CSS-only approach — abusing border-radius with all eight values — gives you animatable, responsive blobs that live in your stylesheet.

The trick is using wildly different horizontal and vertical radii per corner. Something like border-radius: 60% 40% 30% 70% / 60% 30% 70% 40% starts looking organic. The values don't need to follow any pattern — in fact, the more mismatched they are, the more blob-like the result.

// React blob component with CSS animation
export function AnimatedBlob({ color = '#6366f1', size = 300 }) {
  return (
    <div
      style={{
        width: size,
        height: size,
        backgroundColor: color,
        borderRadius: '60% 40% 30% 70% / 60% 30% 70% 40%',
        animation: 'blob-morph 8s ease-in-out infinite',
      }}
    />
  );
}

/*
@keyframes blob-morph {
  0%   { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  50%  { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; }
  100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
}
*/

That animation keyframe approach works well for hero decorations, background accents, avatar frames. Keep will-change: border-radius off by default — only add it if you're actually seeing compositor jank, because it forces layer promotion and chews memory.

In practice, blob animations that loop under 10 seconds look fluid. Go longer and users notice the repetition; go shorter and it reads as twitchy. 8 seconds is a sweet spot.

border-radius in Design Tokens and Tailwind

If you're working in a design system, border-radius should be a token — not a raw px value scattered across components. The standard scale I've seen work well across teams: none: 0, sm: 4px, md: 8px, lg: 16px, xl: 24px, 2xl: 32px, full: 9999px. That's it. Anything outside those values is a one-off that needs a comment.

Tailwind CSS ships rounded-sm through rounded-full out of the box, and since v3.0 you can extend borderRadius in your config to add custom blob values. If you're building with glassmorphism cards, a rounded-3xl (24px) is usually the right default — it's soft without looking like a cartoon.

// tailwind.config.js — add blob token
module.exports = {
  theme: {
    extend: {
      borderRadius: {
        blob: '60% 40% 30% 70% / 60% 30% 70% 40%',
        teardrop: '50% 50% 50% 0',
      }
    }
  }
}

That said, Tailwind's arbitrary value syntax rounded-[60%_40%_30%_70%_/_60%_30%_70%_40%] works but is hideous in JSX. Extract it into a token — your future self will thank you.

When to Use SVG clip-path Instead

Look, border-radius has limits. It can only describe elliptical curves on rectangular elements. If your design calls for concave corners, notched shapes, or truly irregular polygons, clip-path with an SVG <clipPath> is the right tool. No amount of border-radius wizardry gets you a concave indent.

The syntax difference matters: clip-path: polygon(...) for straight-edge shapes, clip-path: path(...) for arbitrary curves including cubic beziers. The path() function landed in Chrome 88 (2021) and is now widely supported. You can generate the path string from Figma, Inkscape, or any online blob generator.

One more thing — clip-path also clips pointer events and overflow. If your shape has interactive children near the edges, test hit areas carefully. A 200px element clipped to a blob might have 40px dead zones in the corners where clicks fall through.

For styles that lean into irregular shapes — neobrutalism components with their hard edges, or the organic softness of claymorphism — knowing when to swap border-radius for clip-path is what separates copy-pasted components from intentional design decisions.

Practical Patterns for Cards, Avatars, and Badges

Cards: the standard 2026 card pattern in most design systems uses border-radius: 16px for desktop and drops to 12px on mobile. That's rounded-2xl in Tailwind. If you're building glassmorphism cards, push to 20–24px — the blur and frosted background read better with a softer edge. Check out the glassmorphism components for examples of how radius interacts with backdrop-filter.

Avatars: circular avatars use border-radius: 50% on a square container. For squircle-style avatars (very common in mobile apps post-2022), go with border-radius: 28% on a square. That's roughly 13px on a 48px avatar, 22px on an 80px one. It's worth noting this doesn't auto-scale — if the container changes size, the corner feel changes too.

Badges: notification dots use border-radius: 9999px. Count badges ("3 items") need a pill shape that expands horizontally — same value, but set min-width: 20px and padding: 0 6px so single digits don't look squished. That 6px is load-bearing; don't let a design review remove it.

/* Scalable count badge */
.badge {
  border-radius: 9999px;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  font-size: 11px;
  line-height: 20px;
  text-align: center;
  display: inline-block;
}

Generating and Previewing Shapes Fast

You don't want to hand-tune eight border-radius values in devtools. Use a generator. Empire UI's box shadow generator covers shadow work, and the glassmorphism generator lets you preview radius values live on frosted-glass cards — both output clean, copy-paste-ready CSS.

Quick aside: browser devtools have improved a lot here. Chrome DevTools since ~version 110 shows a visual corner handle in the element box model when you hover a border-radius value. You can drag it. Most developers still don't know this exists.

For blob generation specifically, blobmaker.app and shapedivider.app export SVG paths you can paste into clip-path: path(...). If you want CSS-only blobs for animation, the eight-value technique above is still your best bet — SVG paths don't animate as smoothly through keyframes without GSAP or a dedicated morph library.

The workflow that actually works: design the blob in Figma, export the SVG, simplify the path in an optimizer, and paste into clip-path: path() for static instances. For animated blobs, hand-write the CSS border-radius version and use it for decorative elements only. Don't animate structural layout shapes — users find it distracting, and it can trigger vestibular issues.

FAQ

Can you animate border-radius with CSS transitions?

Yes, border-radius is animatable. You can transition between any two valid values, including the full eight-value blob syntax. Use transition: border-radius 0.4s ease-in-out or keyframe animations — both work without JavaScript.

What's the difference between border-radius: 50% and border-radius: 9999px?

On a square element they look identical — both give a circle. On a non-square element, 50% gives an ellipse fitted to the element's dimensions, while 9999px gives a pill (stadium) shape with fully circular ends. Use 9999px for buttons and badges.

Why does my blob shape look different in Firefox vs Chrome?

They should render identically for standard values. If you see a difference, check for percentage values on elements with box-sizing: border-box — padding affects the computed base differently across engines in edge cases. Switch to explicit px values to eliminate this.

Does border-radius affect performance?

Static border-radius has no measurable performance cost. Animating it can trigger layer promotion if the browser can't composite it cheaply — test on lower-end devices and add will-change: border-radius only if you measure actual jank, not preemptively.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

CSS clip-path Generator: Polygon, Circle and Inset ShapesFree Glassmorphism CSS Generator (Copy-Paste Tailwind)Mesh Gradients in CSS: From Basic to Advanced in 10 MinutesOrganic Shapes in CSS: Blob Buttons, Fluid Dividers, Amorphous Cards