CSS outline with border-radius: Rounded Focus Rings
Rounded focus rings without box-shadow hacks
Outlines used to stay square around rounded buttons, so many sites removed them and drew a ring with box-shadow instead. Every major browser now bends the outline to match border-radius, so the real outline looks right and stays accessible.
The old hack vs the modern fix
View demobutton {
border-radius: 999px;
}
button:focus {
outline: none;
box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--focus-color);
}button {
border-radius: 999px;
}
button:focus-visible {
outline: 2px solid var(--focus-color);
outline-offset: 3px;
}<button class="rounded-full px-4 py-2 focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-blue-500">Save</button>Outline browser support
Live demo
Why the modern way wins
Matches the shape
The outline follows border-radius, so a pill button gets a pill-shaped ring instead of a square box around it.
Shows in forced colors
Windows High Contrast mode drops box-shadow, so a shadow ring disappears there. A real outline still shows.
Gap without extra layers
outline-offset puts space between the button and the ring, which used to take two stacked shadows.
- Lines Saved
- 2 → 1
- No fake ring
- Old Approach
- outline: none + box-shadow
- Vanishes in forced colors
- Modern Approach
- outline + outline-offset
- Follows border-radius
How it works
Before Chrome and Edge 94, Firefox 88 and Safari 16.4, an outline was always drawn as a rectangle, even around a round element. A rounded button with a square focus ring looked broken, so the common fix was outline: none plus a box-shadow ring that did follow the corners.
Now the outline traces the element's border-radius in all of them. outline-offset moves the ring away from the edge, and the curve grows with it, so a pill button gets an even gap all the way around.
The shadow ring had a hidden cost. Forced colors modes, like Windows High Contrast, remove box shadows, so keyboard users there lost the focus indicator. A real outline survives, and you can still pair it with :focus-visible so mouse clicks don't show it.