
The Accessibility Challenge: Balancing Design and Usability
The balance between aesthetics and accessibility is a delicate one that many web developers struggle with. Focus indicators—those outlines that appear when an element is selected—are essential for accessibility but can sometimes clash with your carefully crafted design.
When it comes to keyboard navigation, visible focus indicators are critical. Many users rely exclusively on keyboards for navigation due to motor disabilities, preference, or efficiency. Without clear visual cues, these users can easily lose track of their position on your page.
Why Default Focus Styles Are Problematic
Browsers apply focus styles inconsistently. Some show a bold blue outline, others a dotted line, and the styling varies across elements. These default styles often conflict with your website’s design language.
Simply removing focus styles (using outline: none
) creates serious accessibility issues. But keeping them can result in visual inconsistencies that designers find frustrating—especially when they appear during mouse clicks where they serve little purpose.
Implementing Context-Aware Focus Styles: A Complete Solution
The ideal approach is to show focus indicators only when they’re truly needed—during keyboard navigation—while keeping them hidden during mouse interaction.
Step 1: Creating a Custom Focus Style
First, let’s create a focus visible style that matches your design system. In this example, we’ll use Tailwind CSS to create a subtle ring effect:
*:focus-visible { @apply !outline-hidden ring-1 ring-secondary ring-inset;}
The focus-visible
pseudo-class is designed to apply styles only when the browser determines focus should be visible (typically during keyboard navigation). However, browser implementations vary, and many mobile browsers apply these styles during touch interactions when they aren’t needed. So this solution is incomplete.
Step 2: Adding a Class to the Body Element
To gain more control, we’ll add a class to the <body>
element that tracks the input method:
<body class="using-mouse"></body>
This class will serve as our state indicator—present when using a mouse, absent when using a keyboard.
Step 3: Implementing Input Detection JavaScript
Now we’ll add a small script to the head of the document that toggles the class based on the user’s input method:
document.body.addEventListener('mousedown', function () { document.body.classList.add('using-mouse');});
document.body.addEventListener('keydown', function (event) { if (event.key === 'Tab') { document.body.classList.remove('using-mouse'); }});
This script does two things:
- Adds the
using-mouse
class whenever a mouse click occurs - Removes the class when the Tab key is pressed, indicating keyboard navigation
The script is lightweight and doesn’t require any dependencies, making it perfect for performance-conscious websites.
Limited Time Launch Sale
Our AstroJS starter template includes this accessibility enhancement pre-configured, along with dozens of other performance and UX optimizations that will save you hours of development time.
GET 60% OFF!Step 4: Applying Focus Styles Conditionally
Finally, we’ll modify our CSS to only show focus styles when the using-mouse
class is absent:
body:not(.using-mouse) *:focus-visible { @apply !outline-hidden ring-1 ring-secondary ring-inset;}
This selector ensures that:
- Focus styles appear during keyboard navigation (when
using-mouse
is removed) - Focus styles remain hidden during mouse interaction
- The experience remains consistent across different browsers and devices
Key Benefits Beyond Visual Improvements
-
Improved User Experience: Mouse users won’t see unnecessary focus indicators that can be distracting
-
Enhanced Accessibility: Keyboard users get clear, consistent focus indicators that follow your design system
-
Design Integrity: Your website maintains its visual coherence while still supporting all users
-
Reduced Support Issues: Fewer users will report “strange blue outlines” appearing on your site
-
WCAG Compliance: This technique helps meet accessibility guidelines without compromises
Browser Compatibility and Fallback Options
This solution works in all modern browsers. For older browsers that don’t support :focus-visible
, you can add a fallback using feature detection:
/* Fallback for browsers that don't support :focus-visible */@supports not selector(:focus-visible) { body:not(.using-mouse) *:focus { @apply !outline-hidden ring-1 ring-secondary ring-inset; }}
By implementing this technique, you create a more inclusive web experience that works for everyone without sacrificing your design vision. Your mouse users get a clean interface, while keyboard users receive the visual guidance they need to navigate effectively.
This small addition to your website represents the best of both worlds—beautiful design and genuine accessibility working together in harmony.
Related Articles

How To Create A Secure Staging Environment For Cloudflare Pages
Testing website changes before they go live is essential for maintaining a professional online presence. Learn how to create a secure, password-protected staging environment for your Cloudflare Pages site.

How To Redirect .pages.dev to Your Domain
Learn how to redirect .pages.dev to your domain with this step-by-step guide

Schedule Cloudflare Pages Builds
Schedule your Cloudflare Pages builds to run at specific times. No external services needed.

Fix Bad Indentation Of A Mapping Entry Error In Astro
Troubleshoot and resolve the common "bad indentation of a mapping entry" error in AstroJS with this practical guide.