How to Fix Missing Focus Indicators Without Ruining Your Design
A focus indicator is the visible marker that shows which element currently has keyboard focus. It is what lets a keyboard user know where they are on the page. If you press Tab and a button, link, input, or menu item receives focus, there should be a clear visual sign. It might be an outline, ring, underline, background change, border, or other visible treatment. Without it, keyboard navigation becomes guesswork.
Missing focus indicators are one of the most common accessibility issues on modern websites. They often happen because developers remove the browser's default outline to make the design look cleaner:
*:focus {
outline: none;
}That one rule can make an entire website difficult or impossible to use by keyboard. The good news is that focus indicators do not have to be ugly. You can create accessible focus styles that fit your brand and still give users a strong visual cue. The goal is not to preserve the default blue outline at all costs. The goal is to make focus visible, consistent, and easy to recognize.
ADA CodeFix flags missing or weak focus indicators because they are high-impact and often easy to fix. This guide explains why focus styles matter, how they relate to WCAG, and how to create practical CSS patterns for buttons, links, forms, navigation menus, and custom components.
This page is informational and is not legal advice. Accessibility requirements can vary by site, organization, and jurisdiction. For legal guidance, consult qualified counsel. Accessibility conformance should be evaluated with a mix of automated scans, manual review, keyboard testing, and professional judgment.
What is keyboard focus?
Keyboard focus is the browser's way of identifying the currently active interactive element. When a user presses Tab, focus moves from one focusable element to the next. Focusable elements usually include:
- Links
- Buttons
- Inputs
- Select menus
- Textareas
- Checkboxes
- Radio buttons
- Elements with
tabindex="0" - Some custom widgets
When an element has focus, keyboard actions usually apply to that element. For example, pressing Enter may activate a link, pressing Space may press a button, and typing may enter text into a focused field. A visible focus indicator answers a simple question: "Where am I right now?" Without that answer, keyboard navigation becomes disorienting.
WCAG criteria related to focus indicators
WCAG 2.4.7 — Focus Visible
This criterion requires that keyboard focus be visible when a user interface component receives focus. If users cannot see focus, they may not be able to operate the page.
WCAG 2.4.11 — Focus Not Obscured
WCAG 2.2 added focus-related criteria that address whether focused content is hidden behind sticky headers, overlays, cookie banners, or other content. Even when focus styles exist, they are not helpful if the focused element is covered.
WCAG 2.1.1 — Keyboard
Focus indicators also support keyboard accessibility more broadly. If a page is technically keyboard operable but the user cannot tell where focus is, the experience still fails in practice.
The most common bad pattern: outline none
The classic mistake is removing outlines globally.
Bad:
a:focus,
button:focus,
input:focus {
outline: none;
}Worse:
*:focus {
outline: none !important;
}This removes the default focus indicator from all interactive elements. If no replacement is provided, keyboard users lose their location.
A better baseline:
:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}This uses the current text color, creates a visible outline, and offsets it so it does not blend into the element's border.
:focus vs :focus-visible
The :focus selector applies whenever an element receives focus. That includes mouse clicks, keyboard navigation, and programmatic focus. The :focus-visible selector is more selective. Browsers apply it when focus should be visibly indicated, usually during keyboard interaction. This helps avoid showing focus rings on every mouse click while still supporting keyboard users.
A common pattern:
:focus {
outline: none;
}
:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}This can be acceptable if your :focus-visible style is strong. But avoid removing focus styles unless you are sure the replacement works across your supported browsers and components.
A safer pattern:
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}This targets common focusable elements without applying unnecessary styles to every element.
What makes a good focus indicator?
A good focus indicator is:
- Visible against the surrounding background
- Consistent across the site
- Not hidden by overflow or clipping
- Not dependent only on color if the change is subtle
- Large enough to notice
- Different from hover state
- Present on every interactive control
- Not obscured by sticky headers or overlays
A small color change from dark gray to slightly darker gray is usually not enough. Users need to see the current position quickly.
Brand-friendly focus styles
You can make focus styles attractive and accessible.
Button focus ring
.button:focus-visible {
outline: 3px solid #111;
outline-offset: 3px;
}If your button is dark, use a light outer ring plus contrast against the background:
.button-primary:focus-visible {
outline: 3px solid #fff;
box-shadow: 0 0 0 6px #111;
}This creates a two-layer ring that can work against mixed backgrounds.
Link focus style
Links can use outlines, underlines, or background changes.
a:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
text-decoration-thickness: 0.15em;
}For inline links inside paragraphs, outlines can sometimes look awkward but are still usable. Another option is a background highlight:
.prose a:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
background: rgba(0, 0, 0, 0.08);
}Do not rely only on removing or adding a faint underline.
Form field focus
Form inputs often need a clear border or ring.
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid #111;
outline-offset: 2px;
border-color: #111;
}If the input already has a border, add an outer ring:
.input:focus-visible {
outline: none;
border-color: #111;
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.25);
}Make sure the box shadow is visible against the page background.
Navigation focus
Navigation links need visible focus, especially if they are in a header.
.nav a:focus-visible,
.nav button:focus-visible {
outline: 2px solid currentColor;
outline-offset: 4px;
border-radius: 4px;
}If your header has overflow clipping, the outline may be cut off. In that case, adjust the container or use an inset style:
.nav a:focus-visible {
outline: none;
box-shadow: inset 0 0 0 2px currentColor;
}Inset focus styles can help when outlines would be clipped, but they must still be visible.
Focus indicators and custom components
Custom components often lose focus styles because they are built from non-semantic elements or because CSS resets remove outlines.
Custom card links
A card may contain a title, image, description, and button. If the whole card is clickable, make sure focus is obvious.
Better pattern:
<article class="card">
<h2>
<a href="/fix/keyboard-navigation" class="card-link">
How to Fix Keyboard Navigation Issues
</a>
</h2>
<p>Learn how to test and fix keyboard access problems.</p>
</article>.card:has(.card-link:focus-visible) {
outline: 3px solid currentColor;
outline-offset: 4px;
}This lets the actual link receive focus while the whole card gets a visible focus treatment.
Icon buttons
Icon-only buttons need both an accessible name and a visible focus style.
<button type="button" class="icon-button" aria-label="Open menu">
<svg aria-hidden="true" focusable="false">...</svg>
</button>.icon-button:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}Tabs
Tabs should show which tab is selected and which tab has focus. These are related but not identical.
.tab[aria-selected="true"] {
border-bottom: 3px solid currentColor;
}
.tab:focus-visible {
outline: 3px solid currentColor;
outline-offset: 4px;
}A selected tab indicator alone may not be enough. Users also need to know where keyboard focus currently is.
Focus not obscured by sticky headers
Even with good focus styles, a focused element can be hidden behind sticky headers, cookie banners, or fixed overlays.
Common issue:
.header {
position: sticky;
top: 0;
}When users skip to content or navigate to anchor links, the target may appear behind the header.
Helpful CSS:
[id] {
scroll-margin-top: 6rem;
}For focusable elements lower on the page, test whether the browser scrolls them into a visible position. If a sticky footer, chat widget, or cookie banner covers important controls, adjust layout or placement.
Manual testing checklist
Use this test after making changes.
- Open the page in a browser.
- Put the mouse aside.
- Press Tab.
- Confirm the first focused element is visible.
- Continue tabbing through the page.
- Confirm every link, button, input, select, textarea, and custom control has a visible focus style.
- Use Shift + Tab to move backward.
- Open menus and modals.
- Confirm focus remains visible inside those components.
- Check the page at mobile and desktop widths.
- Check focus near sticky headers and overlays.
- Confirm focus is not clipped by
overflow: hidden.
If you ever ask "where did focus go?" the page likely needs a stronger focus indicator or a focus-order fix.
How ADA CodeFix detects focus indicator issues
ADA CodeFix can help identify common focus-style problems such as:
- CSS rules that remove outlines
- Interactive elements with no visible focus style
- Focus styles that may be too subtle
- Keyboard focus on elements that are hidden or clipped
- Custom buttons or controls that may not expose focus properly
- Components where focus can move but the visual state is unclear
Automated detection has limits. A scanner can detect missing or risky CSS patterns, but it cannot always judge whether a custom focus style is visually strong enough in every context. Manual testing is still important.
Common mistakes to avoid
Mistake 1: Making hover and focus identical but subtle
Hover styles are often designed for mouse users. Focus styles need to support keyboard orientation. If both are a faint color change, the focus state may not be enough.
Mistake 2: Clipping outlines
Containers with overflow: hidden can cut off outlines.
.card {
overflow: hidden;
}If the focused element is inside, its outline may be clipped. Use outline-offset, inner box shadows, or adjust container overflow.
Mistake 3: Styling only buttons, not links
Many pages style button focus but forget text links, navigation links, card links, logo links, pagination, breadcrumbs, and footer links.
Mistake 4: Forgetting disabled-like states
Sometimes controls look disabled but are still focusable. If users can focus an element, make the focus state visible and explain what the control does.
Mistake 5: Assuming the browser default is always present
CSS resets, component libraries, and design systems often remove default outlines. Review global CSS carefully.
Platform-specific notes
WordPress
Themes often remove focus outlines globally. Check the theme stylesheet for outline: none. Also test menus, forms, sliders, and plugin-generated buttons.
Shopify
Product cards, variant selectors, cart drawers, and navigation menus commonly need focus review. Many themes make strong hover styles but weak keyboard focus styles.
Webflow
Custom interactions can create attractive hover states but leave focus states unfinished. Check the Style panel and custom code for each interactive component.
React and Next.js
Design systems should include focus styles at the component level. Buttons, links, inputs, cards, tabs, modals, and menus should have consistent focus-visible treatment. A reusable button component should include focus styles by default:
function Button({ children, ...props }) {
return (
<button
className="inline-flex rounded-md px-4 py-2 focus-visible:outline focus-visible:outline-3 focus-visible:outline-offset-4"
{...props}
>
{children}
</button>
);
}Final takeaway
A missing focus indicator turns keyboard navigation into a guessing game. Users need to know where they are before they can decide what to do next.
The fix is usually straightforward: do not remove outlines without replacing them, use :focus-visible, make the focus state strong enough to see, and test every important interaction with the keyboard. Good focus styles can match your brand and still meet user needs. ADA CodeFix can help flag missing or risky focus patterns and generate developer-reviewable CSS suggestions. The final check is simple: tab through the page and make sure you never lose your place.
Sources
- W3C WCAG Understanding 2.4.7 Focus Visible (opens in new tab)
- W3C WCAG Understanding 2.4.11 Focus Not Obscured (opens in new tab)
- MDN :focus-visible (opens in new tab)
- MDN outline (opens in new tab)
- W3C Web Accessibility Initiative (WAI) (opens in new tab)
Run a free WCAG 2.1 AA scan on your site
ADA CodeFix scans your pages, identifies likely WCAG failures, and generates developer-reviewable code fixes for focus styles, labels, alt text, color contrast, and more.
Scan My Site FreeRelated guides
Fix clickable divs, hover-only menus, and focus traps.
Missing form labelsFix unlabeled inputs, placeholder-only fields, and unlabeled checkboxes.
WCAG 2.4.7 Focus VisibleWhy keyboard focus must be visible and how to test for it.
WCAG 2.1.1 KeyboardMake all functionality operable through the keyboard interface.