// blog/developer/
Back to Blog
Developer · April 18, 2026 · 7 min read

The Complete Guide to CSS Border Radius and Box Shadows

The Complete Guide to CSS Border Radius and Box Shadows

Rounded corners and shadows are two of the most used CSS properties in modern web design. Every card, button, modal, and dropdown you see on the web uses border-radius for rounded corners and box-shadow for depth. They are simple properties with straightforward syntax, but there are enough variations and gotchas to trip you up if you do not use them regularly.

The Border Radius Tool and Shadow Generator let you dial in exact values visually and copy the CSS. No guessing, no refreshing the browser to check if 12px or 16px looks better.

* * *

Border Radius: From Rounded Corners to Circles

The border-radius property accepts 1, 2, 3, or 4 values, each controlling different corners:

One value: applies to all four corners. `css border-radius: 12px; `

Two values: first applies to top-left and bottom-right, second to top-right and bottom-left. `css border-radius: 12px 0; `

Four values: top-left, top-right, bottom-right, bottom-left (clockwise from top-left). `css border-radius: 12px 8px 0 4px; `

Percentage values: border-radius: 50% on a square element creates a perfect circle. On a rectangle, it creates an ellipse. This is the standard technique for circular avatar images.

Pill shape: border-radius: 9999px (or any very large value) on a rectangular element creates a pill shape, where the short sides are fully rounded. This is how tags, badges, and pill buttons are made.

The Border Radius Tool has sliders for each corner independently, plus a visual preview. This is especially useful for asymmetric border-radius values, where one corner is rounded and others are sharp. These create distinctive shapes for cards, callouts, and decorative elements.

Modern web interface with rounded UI elements
Modern web interface with rounded UI elements
* * *

Box Shadow: The Property That Creates Depth

box-shadow takes up to 6 values: `css box-shadow: [inset] ; `

x-offset: horizontal shadow position. Positive values push the shadow right, negative values push left.

y-offset: vertical shadow position. Positive values push down, negative values push up. A shadow with only a y-offset (no x-offset) creates a "light from directly above" effect, which is the most natural-looking shadow direction.

blur: how soft the shadow edge is. 0 is a hard edge. Higher values create softer, more diffuse shadows. Most UI shadows use blur values between 4px and 24px.

spread: expands or contracts the shadow. Positive values make the shadow larger than the element. Negative values make it smaller. A spread of 0 means the shadow is the same size as the element.

color: usually a semi-transparent black. rgba(0, 0, 0, 0.1) is a subtle shadow. rgba(0, 0, 0, 0.3) is more prominent. Using pure black (#000) without transparency looks harsh and unnatural.

The Shadow Generator lets you adjust each parameter with sliders and see the result in real time. It also supports multiple shadow layers, which is how you create the most realistic depth effects.

Key takeaway

`box-shadow` takes up to 6 values: ```css box-shadow: [inset] <x-offset> <y-offset> <blur> <spread> <color>; ``` **x-offset**: horizontal shadow position.

* * *

Shadow Recipes for Common UI Elements

Card shadow (subtle elevation): `css box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06); ` Two layers: a tight, slightly darker shadow for crispness, and a softer ambient shadow for depth. This is what Tailwind CSS uses for its shadow-sm.

Button shadow (interactive element): `css box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: box-shadow 0.2s ease; ` On hover, increase the shadow to suggest the button is lifting: `css button:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } `

Modal/dialog shadow (high elevation): `css box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 8px 20px rgba(0, 0, 0, 0.1); ` Large, diffuse shadows that make the modal feel like it is floating well above the page.

Inset shadow (pressed state): `css box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); ` Makes the element look pressed into the page. Used for input fields, toggle buttons in their "on" state, and well-style containers.

The Button Generator combines border-radius and box-shadow with other button styles, giving you complete, ready-to-use button CSS.

UI design mockup with shadow and depth effects
UI design mockup with shadow and depth effects
* * *

Combining Border Radius and Box Shadow

Box shadows automatically follow the border-radius shape. If your element has border-radius: 50% (a circle), the shadow is also circular. This is one of those CSS behaviors that "just works" and is easy to take for granted.

One subtlety: when combining large border-radius values with large spread values on box-shadow, the shadow can look oddly shaped at extreme values. The shadow's border-radius is calculated as the element's border-radius plus the spread value. For most practical cases, this is not an issue, but it can produce unexpected shapes on elements with very small border-radius and very large spread.

A polished card design might combine: `css .card { border-radius: 16px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.08); transition: box-shadow 0.3s ease, transform 0.3s ease; } .card:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.12); transform: translateY(-2px); } `

The hover effect increases shadow size and slightly lifts the card. The translateY(-2px) sells the illusion that the card is physically rising off the page. This is a standard interaction pattern on card-based layouts across the web.

Key takeaway

Box shadows automatically follow the border-radius shape.

* * *

FAQ

Does border-radius work on images?

Yes. Apply border-radius: 50% to an element or its container to create circular images. For this to produce a perfect circle, the image (or container) must be square. On a rectangular image, 50% creates an ellipse.

Can I animate box-shadow?

Yes, but with a performance caveat. Animating box-shadow triggers repaint on every frame, which can cause jank on lower-end devices. A more performant approach is to use a pseudo-element (::after) with the hover shadow already applied and opacity: 0, then animate only the pseudo-element's opacity on hover. Opacity changes are GPU-accelerated and much smoother.

How do I add a shadow to text instead of a box?

text-shadow is a separate property with similar syntax but without the spread and inset parameters: `css text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); ` Use it sparingly. Text shadows that are too prominent reduce readability.

Why does my shadow look different on Mac and Windows?

Rendering engines handle sub-pixel shadow rendering slightly differently. macOS tends to produce softer-looking shadows due to its different approach to sub-pixel anti-aliasing. The differences are subtle and generally not worth compensating for. Design your shadows on whichever platform you use, and they will look acceptable on both.