Key insights
- outline: none isn't a style choice — remove the default focus ring and you've shipped an accessibility failure. If you kill it, replace it with something better.
- A proper focus ring needs three things: 2px thickness, a 2px offset, and enough contrast to stay visible on both light and dark backgrounds.
- :focus-visible tells mouse and keyboard apart — a click gets no ring, a Tab press gets one — so keyboard users can navigate without cluttering the pointer experience.
- Focus follows the DOM order, not your visual layout. Reorder columns with CSS and Tab starts teleporting across the page — keep visual order and DOM order in sync.
- Inside a modal, trap the focus: Tab should cycle through the dialog and wrap around, and Escape should close it and hand focus back to the element that opened it.
- A skip link jumps past dozens of nav links in a single keypress. Keep it invisible until focused, and make it the first element on the page.
Do / Don't
- Do: Replace a removed outline with a custom ring — 2px thick, offset, and contrasting on every background
- Do: Reach for :focus-visible so keyboard users get a ring while mouse clicks stay clean
- Do: Place a skip link as the first focusable element, hidden until focused
- Don't: Set outline: none without shipping a visible replacement
- Don't: Reorder content with CSS and let the DOM order drift from the visual order
- Don't: Let a modal leak focus to the page behind it, or drop focus when it closes