Shadows vs borders for depth
Sep 18, 2026 · Interface · 3 min read
Try this on whatever you are designing right now: delete every border on your cards and panels, and give each one a soft layered shadow instead. The screen gets quieter, and somehow more three-dimensional. Here is why that works, and where borders still belong.
A 1px solid border is the first tool most of us reach for to separate a card from the page. It works, but it draws a hard line with no sense of depth, and it comes with side effects in layout and in rounded corners. A stacked box-shadow usually does the job better.
Borders versus shadows
The shadow version is doing three things at once:
- A 1px ring at very low opacity, which defines the edge like a border would.
- A tight, small shadow just under the element, which says the element sits on the surface.
- A soft, wider shadow, which gives it a little lift.
:root {
--shadow-card:
0 0 0 1px rgb(0 0 0 / 0.06),
0 1px 2px -1px rgb(0 0 0 / 0.06),
0 2px 4px 0 rgb(0 0 0 / 0.04);
--shadow-card-hover:
0 0 0 1px rgb(0 0 0 / 0.08),
0 1px 2px -1px rgb(0 0 0 / 0.08),
0 2px 4px 0 rgb(0 0 0 / 0.06);
}
.card {
box-shadow: var(--shadow-card);
transition: box-shadow 150ms ease-out;
}There are practical wins too. A shadow takes no layout space, so switching between a flat and a raised state never shifts the content by a pixel. It follows border-radius perfectly. And because both states are lists with the same number of layers, the browser can animate between them smoothly.
When a border is still right
Use a border for things that are lines by nature: table rules, dividers, input fields that need a clear boundary for accessibility, and high-contrast modes. Shadows are also removed in Windows forced-colors mode, so critical boundaries such as form fields should keep a real border or a transparent one that the system can color in.
The image outline
Photos and screenshots have their own problem: a bright image on a white page has no edge. The sky in a photo bleeds straight into the background. The fix is almost invisible: a 1px inset outline at 8% black on light pages, 8% white on dark ones.

You might try an inset box-shadow, but on an <img> it is painted underneath the picture, so you never see it. Use an outline pulled inward instead:
img.thumb {
outline: 1px solid rgb(0 0 0 / 0.08);
outline-offset: -1px;
border-radius: 12px; /* outlines follow the radius in modern browsers */
}
.dark img.thumb {
outline-color: rgb(255 255 255 / 0.08);
}Because it is translucent black rather than gray, it darkens whatever it sits on by the same small amount. On a dark photo you cannot see it at all; on a white one it draws exactly the edge you need.
Checklist
- Cards use a layered shadow token, not a bare 1px border.
- Rest and hover shadows have the same number of layers.
- Form fields and dividers keep real borders.
- Images and thumbnails have a 1px inset outline at 8% opacity.
- Nothing jumps by a pixel when it gains or loses its edge.
This piece expands on the Interface rules in my cheat sheet, where every rule has a live example.
Keep readingHow fast UI animations should beThe more often something happens, the less it should animate. Press feedback, hover timing, menus and page loads.