CSS Border Radius: A Complete Guide to Rounded Corners and Shapes
This guide has a free tool → Open Tailwind to CSS converter
What Is border-radius?
The border-radius CSS property rounds the corners of an element's border box. It is one of the most commonly used CSS properties - nearly every modern UI uses rounded corners. Before border-radius was widely supported, achieving rounded corners required images, JavaScript, or complex layered markup. Today, a single CSS property does all of it.
.card {
border-radius: 8px;
}This applies an 8px radius to all four corners. The higher the value, the more pronounced the rounding. A value equal to half the element's smallest dimension creates a circle or capsule.
Understanding border-radius fully - including the elliptical syntax, the percentage-based behavior, and its interaction with overflow - unlocks everything from standard UI components to complex organic shapes.
Tailwind to CSS
Free online tailwind to CSS - convert Tailwind CSS classes to vanilla CSS properties
CSS Box Shadow Generator
Free online CSS box shadow generator - create beautiful CSS box shadows with a visual builder and live preview
CSS Gradient Generator
Free online CSS gradient generator - create beautiful CSS gradients with a visual editor and live preview
How Rounded Corners Work Geometrically
Each corner of an element is shaped by an arc of a circle (or ellipse). The border-radius value defines the radius of that circle.
For border-radius: 8px, each corner uses a circle with an 8px radius. The arc starts 8px from the corner along each edge and curves to meet itself, creating a smooth rounded corner.
When the total radii of adjacent corners exceeds the element's dimension, browsers reduce all radii proportionally so they fit within the element - this is why border-radius: 50% reliably creates a circle on any square element without overflowing.
The Syntax
Single Value (All Corners)
border-radius: 8px;Applies the same radius to all four corners. This is the most common form.
Two Values (Diagonal Pairs)
border-radius: 8px 0;
/* top-left/bottom-right: 8px, top-right/bottom-left: 0 */
border-radius: 12px 4px;
/* top-left/bottom-right: 12px, top-right/bottom-left: 4px */Two values apply to diagonal pairs. The first value covers top-left and bottom-right; the second covers top-right and bottom-left. This creates an asymmetric visual rhythm.
Three Values
border-radius: 8px 16px 4px;
/* top-left: 8px, top-right/bottom-left: 16px, bottom-right: 4px */Three values follow the pattern: top-left, top-right/bottom-left, bottom-right.
Four Values (Each Corner)
border-radius: 8px 16px 24px 0;
/* top-left: 8px, top-right: 16px, bottom-right: 24px, bottom-left: 0 */The order is clockwise starting from the top-left corner: top-left, top-right, bottom-right, bottom-left. The same clockwise-from-top-left pattern used by margin, padding, and border-width.
Individual Corner Properties
You can also set each corner independently:
border-top-left-radius: 8px;
border-top-right-radius: 16px;
border-bottom-right-radius: 24px;
border-bottom-left-radius: 0;This is useful when building dynamic styles where only one corner needs to change, or when working with CSS custom properties that control one corner at a time.
Elliptical Radius - The Slash Syntax
This is where border-radius becomes genuinely powerful. You can specify different horizontal and vertical radii for each corner using the slash separator:
border-radius: 50px / 25px;
/* horizontal radius: 50px, vertical radius: 25px */This creates elliptical corners instead of circular ones. The slash separates horizontal values (before) from vertical values (after).
The full eight-value syntax:
border-radius: TL-h TR-h BR-h BL-h / TL-v TR-v BR-v BL-v;This gives you independent control over the horizontal and vertical radius of each of the four corners - eight values total. This is how you create organic blob shapes, asymmetric layouts, and complex decorative elements.
Example:
.organic {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}Common Shapes
Circle
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
}50% on a square element creates a perfect circle. This is the standard technique for circular avatars, profile images, step indicators, and icon buttons. The percentage-based approach works regardless of the element's actual pixel dimensions.
Pill / Capsule
.pill {
display: inline-flex;
align-items: center;
padding: 6px 16px;
border-radius: 9999px;
}A very large radius on a rectangular element creates a pill shape. 9999px (or 999em) is used instead of 50% because 50% creates an ellipse on a rectangle - the horizontal radius would be 50% of the width and the vertical radius would be 50% of the height, causing irregular corners on very wide elements.
Using 9999px guarantees fully rounded short ends regardless of the element's dimensions.
Standard UI Rounded Rectangle
.badge {
border-radius: 4px;
}
.button {
border-radius: 6px;
}
.input {
border-radius: 6px;
}
.card {
border-radius: 12px;
}
.modal {
border-radius: 16px;
}
.drawer {
border-radius: 16px 0 0 16px;
}Most design systems define a consistent radius scale rather than using arbitrary values:
| Element | Common Radius | Rationale |
|---|---|---|
| Checkboxes, small badges | 2-4px | Slight softening without heavy rounding |
| Inputs, buttons | 4-8px | Readable form, feels interactive |
| Cards, list items | 8-12px | Distinct card feel, matches modern design |
| Modals, dialogs | 12-16px | Elevated surface with clear boundaries |
| Full pill labels | 9999px | Always-rounded regardless of width |
| Circles (avatars) | 50% | Perfect circle on square element |
Organic Blob Shape
.blob {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
background: linear-gradient(135deg, #667eea, #764ba2);
width: 400px;
height: 300px;
}The slash syntax with asymmetric percentage values creates irregular, organic shapes. These are popular for:
- Hero section background decorations
- Illustration-style UI elements
- Abstract background shapes in landing pages
- Decorative accents behind content
Animating blob shapes creates fluid, organic motion:
.blob {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
animation: morph 8s ease-in-out infinite;
}
@keyframes morph {
0%, 100% {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}
25% {
border-radius: 58% 42% 75% 25% / 76% 46% 54% 24%;
}
50% {
border-radius: 50% 50% 33% 67% / 55% 27% 73% 45%;
}
75% {
border-radius: 33% 67% 58% 42% / 63% 68% 32% 37%;
}
}Chat Bubble
.message-sent {
border-radius: 18px 18px 4px 18px;
/* bottom-right corner is sharp, pointing toward sender */
}
.message-received {
border-radius: 18px 18px 18px 4px;
/* bottom-left corner is sharp, pointing toward sender */
}Notched/Partial Rounding
/* Only top corners rounded - for bottom-attached card */
.card-top {
border-radius: 12px 12px 0 0;
}
/* Only bottom corners rounded */
.card-bottom {
border-radius: 0 0 12px 12px;
}
/* Single corner - decorative accent */
.accent-corner {
border-radius: 0 32px 0 0;
}
/* Diagonal corners */
.diagonal {
border-radius: 32px 0 32px 0;
}Tab Navigation
Tabs typically have rounded top corners and flat bottom corners so they appear to connect with the content panel below them:
.tab {
border-radius: 8px 8px 0 0;
border-bottom: none;
}
.tab-panel {
border-radius: 0 8px 8px 8px;
}
/* Active tab connects to panel */
.tab.active + .tab-panel {
border-top-left-radius: 0;
}Input with Icon Button
.input-group {
display: flex;
border-radius: 8px;
overflow: hidden;
}
.input-group input {
border-radius: 8px 0 0 8px;
border-right: none;
flex: 1;
}
.input-group button {
border-radius: 0 8px 8px 0;
border-left: none;
}border-radius With Percentages vs Pixels vs rem
Pixels
Fixed radius regardless of element size. border-radius: 8px looks the same on a 40px button and a 400px modal. Use pixels when you want the rounding to remain constant as the element resizes.
Percentages
Relative to the element's dimensions. The horizontal radius is a percentage of the element's width; the vertical radius is a percentage of the element's height.
/* Square -> circle */
.avatar {
width: 64px;
height: 64px;
border-radius: 50%; /* 32px / 32px: perfect circle */
}
/* Rectangle -> ellipse */
.hero-bg {
width: 800px;
height: 300px;
border-radius: 50%;
/* 400px horizontal, 150px vertical: an ellipse */
}Percentages make the radius scale with the element. This is useful for shapes that must remain circular regardless of their rendered size.
rem
Relative to the root font size. Useful for design systems that scale with the user's font-size preference:
:root {
font-size: 16px;
}
.button {
border-radius: 0.375rem; /* 6px at default font size */
}Using rem for border-radius is uncommon in practice - most designers want the rounding to be independent of font size. Pixels are more predictable for this use case.
Rule of thumb: Use percentages for circles and organic shapes. Use pixels or rem for UI components (cards, buttons, inputs, modals).
Design Tokens for Consistent Radius
One of the most common UI mistakes is inconsistent border-radius values across components. Using 4px on one button, 6px on another, and 10px on a card creates a visually incoherent experience.
Define a radius scale in CSS custom properties:
:root {
--radius-none: 0;
--radius-xs: 2px;
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
--radius-2xl: 16px;
--radius-3xl: 24px;
--radius-full: 9999px;
}Use these tokens consistently:
.badge { border-radius: var(--radius-sm); }
.button { border-radius: var(--radius-md); }
.input { border-radius: var(--radius-md); }
.card { border-radius: var(--radius-xl); }
.modal { border-radius: var(--radius-2xl); }
.avatar { border-radius: var(--radius-full); }
.tag { border-radius: var(--radius-full); }Tailwind CSS Radius Scale
If you use Tailwind CSS, the built-in radius scale follows a similar pattern:
| Class | Value |
|---|---|
rounded-none | 0px |
rounded-sm | 2px |
rounded | 4px |
rounded-md | 6px |
rounded-lg | 8px |
rounded-xl | 12px |
rounded-2xl | 16px |
rounded-3xl | 24px |
rounded-full | 9999px |
You can use the Tailwind to CSS converter to translate Tailwind classes to raw CSS values.
Interaction With Other CSS Properties
overflow: hidden
border-radius rounds the corners of the element's border box, but child content does not clip automatically. A child element can visually overflow the rounded corners:
/* Child image leaks out of the rounded corners */
.card {
border-radius: 12px;
/* Without overflow: hidden, an image inside will not be clipped */
}
/* Add overflow hidden to contain child content */
.card {
border-radius: 12px;
overflow: hidden;
}This is especially important for:
- Cards with header images
- Circular avatar images
- Video players with rounded corners
- Any element where a child fills the full width or height
Rounded Image Avatar
.avatar-container {
width: 48px;
height: 48px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
}
.avatar-container img {
width: 100%;
height: 100%;
object-fit: cover;
display: block; /* Remove inline image baseline gap */
}Using overflow: hidden on a container and rounding the container - rather than applying border-radius directly to the img tag - provides more consistent behavior across browsers and compositing layers.
border-radius and box-shadow
box-shadow follows the border-radius of the element. A rounded element has a rounded shadow automatically:
.card {
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
/* Shadow is rounded at the corners to match the element */
}Use the Box Shadow Generator to create layered shadow effects that work harmoniously with your border-radius values.
border-radius and Gradients
Gradients respect border-radius automatically:
.gradient-card {
border-radius: 16px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}The gradient fills the rounded box, clipping at the corners. Combine with the Gradient Generator to create gradient backgrounds that complement your rounded components.
border-radius and transitions
You can animate border-radius for interactive effects:
.button {
border-radius: 8px;
transition: border-radius 0.2s ease;
}
.button:hover {
border-radius: 16px;
}However, be aware that animating border-radius can trigger repaints and is more expensive than animating transform or opacity. For high-performance animations on many elements simultaneously, consider whether the visual effect justifies the cost.
Common Mistakes
Using border-radius on Table Cells
/* This does NOT work */
td {
border-radius: 8px;
border-collapse: collapse; /* Prevents border-radius from working */
}
/* Fix: use separate instead of collapse */
table {
border-collapse: separate;
border-spacing: 0;
}
td {
border-radius: 8px;
}
/* Or: apply radius to a wrapper div instead */border-radius does not work on table cells when border-collapse: collapse is applied. Use border-collapse: separate or apply the rounding to a wrapper element.
Forgetting overflow: hidden on Image Containers
/* Image overflows the rounded corners */
.card {
border-radius: 12px;
/* Missing: overflow: hidden */
}
.card img {
width: 100%;
}
/* Fixed */
.card {
border-radius: 12px;
overflow: hidden;
}Using border-radius: 50% on Rectangles When You Want a Pill
/* Creates an ellipse, not a pill shape */
.tag {
width: 120px;
height: 32px;
border-radius: 50%; /* 60px horizontal, 16px vertical - looks odd */
}
/* Creates a true pill */
.tag {
width: 120px;
height: 32px;
border-radius: 9999px; /* Always fully rounded */
}Inconsistent Radius Values
Using ad-hoc values (3px here, 7px there, 11px somewhere else) makes a UI feel undesigned. Always work from a defined scale and use CSS custom properties or design tokens to enforce consistency.
Rounding the Image Directly
/* Less reliable across browsers */
img.avatar {
border-radius: 50%;
width: 48px;
height: 48px;
}
/* More reliable: round the container */
.avatar-wrapper {
border-radius: 50%;
overflow: hidden;
width: 48px;
height: 48px;
}
.avatar-wrapper img {
width: 100%;
height: 100%;
object-fit: cover;
}Performance Considerations
border-radius is generally inexpensive. Modern browsers handle it at the compositing layer. A few situations worth being mindful of:
Animating border-radius: Animation triggers layout and repaint on every frame. For many simultaneously animated elements this can cause jank. Profile with DevTools before committing to border-radius animation on heavily animated UIs.
Very large elements with border-radius and overflow: hidden: Clipping a large element's overflow forces the browser to create a new stacking context. This is usually fine but can affect z-index and compositing behavior for overlapping elements.
box-shadow on many rounded elements: Box shadows are rendered by the CPU by default. Large shadows on many elements can impact performance on low-end hardware. Use filter: drop-shadow() for GPU-accelerated alternatives when needed.
Advanced Techniques
Squircle (Superellipse)
A squircle is a hybrid between a square and a circle - it avoids the "sharp corners at the corners of the circle" problem. iOS uses squircles for app icons. CSS does not have native squircle support, but you can approximate with SVG clip-path or very careful border-radius tuning:
/* Close approximation of iOS-style squircle */
.squircle {
border-radius: 22.37%;
}For true squircles, SVG clip-path or clip-path: path() with a superellipse formula provides better accuracy.
Responsive Border Radius with clamp()
For elements that scale across viewport sizes:
.hero-card {
border-radius: clamp(8px, 2vw, 24px);
/* Scales from 8px at small screens to 24px at large screens */
}CSS Custom Property Theming
Expose border-radius as a theme variable:
:root {
--brand-radius: 8px;
}
.button, .card, .input, .badge {
border-radius: var(--brand-radius);
}
/* Rounded theme variant */
[data-theme="rounded"] {
--brand-radius: 16px;
}
/* Sharp theme variant */
[data-theme="sharp"] {
--brand-radius: 2px;
}This lets users or design system consumers switch between radius aesthetics with a single variable change.
Asymmetric Cards
.feature-card {
border-radius: 4px 24px 4px 24px;
/* Diagonal asymmetry creates a distinctive card shape */
}
.angled-card {
border-radius: 0 0 40% 0 / 0 0 100px 0;
/* One dramatic elliptical corner for visual interest */
}border-radius in Practice: Component Examples
Complete Button System
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 500;
cursor: pointer;
transition: background 0.15s, transform 0.1s;
}
/* Size variants */
.btn-sm { padding: 4px 12px; border-radius: 4px; font-size: 0.875rem; }
.btn-md { padding: 8px 16px; border-radius: 6px; font-size: 1rem; }
.btn-lg { padding: 12px 24px; border-radius: 8px; font-size: 1.125rem; }
/* Shape variants */
.btn-pill { border-radius: 9999px; }
.btn-square { border-radius: 0; }
/* Icon button */
.btn-icon {
width: 40px;
height: 40px;
padding: 0;
border-radius: 50%;
}Card Component
.card {
background: white;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06);
overflow: hidden;
}
.card-header {
/* No top radius needed - overflow: hidden on parent clips it */
padding: 20px 24px 0;
}
.card-image {
width: 100%;
aspect-ratio: 16/9;
object-fit: cover;
display: block;
}
.card-body {
padding: 20px 24px;
}
.card-footer {
padding: 16px 24px;
border-top: 1px solid #f0f0f0;
}Input Group
.input-group {
display: flex;
align-items: stretch;
border: 1px solid #d1d5db;
border-radius: 8px;
overflow: hidden;
transition: border-color 0.15s;
}
.input-group:focus-within {
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
}
.input-group-prefix {
display: flex;
align-items: center;
padding: 0 12px;
background: #f9fafb;
border-right: 1px solid #d1d5db;
color: #6b7280;
font-size: 0.875rem;
white-space: nowrap;
}
.input-group input {
flex: 1;
border: none;
outline: none;
padding: 10px 12px;
font-size: 1rem;
background: transparent;
}
.input-group button {
border: none;
border-left: 1px solid #d1d5db;
background: #f9fafb;
padding: 0 16px;
cursor: pointer;
transition: background 0.15s;
}
.input-group button:hover {
background: #f3f4f6;
}Generate Border Radius Values Visually With ToolBox
Crafting the perfect border-radius value - especially with the slash syntax for organic shapes - is difficult to do by hand. Adjusting eight independent values and predicting the resulting shape requires trial and error.
The Border Radius Generator lets you:
- Drag handles on a visual preview to adjust each corner independently
- Control horizontal and vertical radii separately using the slash syntax
- See the CSS value update in real time as you drag
- Preview your shape on a realistic element
- Copy the generated CSS with one click
For complementary CSS effects:
- Box Shadow Generator - create layered shadows that enhance rounded elements
- Gradient Generator - design gradient fills that complement your rounded shapes
- CSS Grid Generator - lay out rounded cards in structured grids
- CSS Flexbox Generator - arrange rounded components in flexible layouts
- Color Contrast Checker - ensure your rounded UI elements meet accessibility contrast requirements
Try It Free
Generate border-radius values visually in your browser. Free, private, no signup required.
Need more CSS generators? Try the Box Shadow Generator for layered shadows, the Gradient Generator for background fills, or the CSS Animation Generator for animated shape morphing.
Related Tools
Free, private, no signup required
CSS Flexbox Generator
Flexbox generator - visual CSS flexbox layout builder with live preview and ready-to-copy CSS code
CSS Grid Generator
Free online CSS grid generator - visual CSS grid layout builder with live preview and code export
CSS Formatter
Free online CSS formatter - format and beautify CSS code with configurable options
HTML to JSX Converter
Free online HTML to JSX converter - convert HTML markup to valid React JSX with automatic attribute and style transformations
You might also like
Want higher limits, batch processing, and AI tools?