Lesson 28 of 32
Shadows, Borders and Gradients
border-radius including elliptical corners and pill/circle shortcuts, box-shadow syntax with inset and stacked shadows, radial-gradient(), and text-shadow.
Flat rectangles with sharp corners are the default. A small set of properties is responsible for almost every piece of polish that makes an interface look deliberately designed rather than merely functional — rounded corners, soft depth, a glow, a radiating background.
border-radius
The basic case rounds all four corners equally:
.card {
border-radius: 12px;
}Two long-standing shortcut patterns come up constantly:
.pill { border-radius: 9999px; } /* any value larger than half the height works */
.circle { border-radius: 50%; width: 60px; height: 60px; }border-radius: 9999px on an element with a fixed height rounds the two ends
into a full pill/stadium shape, because the radius is clamped to whatever the
actual geometry allows — you don't need to calculate half the element's
height by hand. border-radius: 50% on a perfectly square element (equal
width and height) produces a true circle, since a 50% radius rounds each
corner all the way to the center of its adjacent edge.
A less common but useful trick: each corner can take two values, separated by a slash — the first controls the corner's horizontal radius, the second its vertical radius, producing an elliptical rather than circular corner:
.leaf-shape {
border-radius: 50px / 20px;
}This rounds every corner with a wide, shallow ellipse (50px across, 20px
tall) rather than a uniform circular curve — useful for organic, non-uniform
shapes that a single-value border-radius can't produce.
box-shadow
box-shadow draws a shadow around an element's box. The full syntax is
offset-x offset-y blur-radius spread-radius color:
.card {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}Reading each value:
offset-x— horizontal shift.0keeps the shadow centered left-right.offset-y— vertical shift. Positive pushes it downward, which is the common "light source above" look.blur-radius— how soft the shadow's edge is.0gives a hard-edged shadow; larger values feather it out.spread-radius(optional) — grows or shrinks the shadow's shape before blurring, independent of the offset.color— usually a low-opacity black or the surface's own darkened tone, since a fully opaque shadow tends to look harsh.
Adding the inset keyword flips the shadow to draw inside the element's
border instead of outside it — useful for a pressed-in, recessed look:
.input-pressed {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}You can stack multiple shadows on one element by separating them with commas, which lets you build up a more realistic, layered depth effect than one shadow alone usually achieves:
.elevated-card {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.08),
0 4px 12px rgba(0, 0, 0, 0.10),
0 12px 24px rgba(0, 0, 0, 0.08);
}Each shadow in the list is drawn independently, closest-to-the-element first; combining a tight, subtle shadow with a larger, softer one tends to read as more natural depth than a single broad shadow.
radial-gradient()
You've already met linear-gradient() for straight-line color transitions.
radial-gradient() works the same way but radiates outward from a center
point instead of along a line:
.spotlight {
background-image: radial-gradient(circle, #fef08a, #f97316);
}The same color-stop syntax from linear-gradient() applies — you can add as
many stops as you like, and pin them to specific positions:
.glow {
background-image: radial-gradient(
circle at top left,
rgba(59, 130, 246, 0.4) 0%,
transparent 70%
);
}circle at top left moves the gradient's center away from the default
(the element's own center) to a specific corner — useful for a soft
directional glow rather than a centered spotlight.
text-shadow
text-shadow uses the exact same offset/blur/color syntax as box-shadow
(minus spread-radius and inset, neither of which apply to text), but
draws the shadow behind the glyphs of the text itself rather than around an
element's box:
.hero-heading {
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}Like box-shadow, multiple comma-separated shadows stack — a common trick
for a subtle outline effect is two or more offset shadows in different
directions layered on the same text.
Try it yourself
What to remember
border-radiusrounds all four corners;9999pxmakes a pill,50%on a square makes a circle, and a slash (50px / 20px) rounds a corner elliptically.box-shadow: offset-x offset-y blur-radius spread-radius color, withinsetfor a recessed look; comma-separate multiple shadows to stack them for realistic depth.radial-gradient()uses the same color-stop syntax aslinear-gradient()but radiates outward from a center point instead of along a line.text-shadowuses the same offset/blur/color syntax asbox-shadow, applied to the text itself rather than the element's box.