Generate keyboard event handlers for accessible navigation
// Keyboard handler for custom button
function handleKeyDown(event) {
// Activate on Enter or Space
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
handleClick(event);
}
}
// Usage
<div
role="button"
tabindex="0"
onkeydown={handleKeyDown}
onclick={handleClick}
>
Custom Button
</div><!-- Good: Natural DOM order -->
<button>First</button>
<button>Second</button>
<button>Third</button>
<!-- Bad: Using positive tabindex -->
<button tabindex="3">Third</button>
<button tabindex="1">First</button>
<button tabindex="2">Second</button>/* Good: Visible focus indicator */
button:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
/* Bad: Removing focus indicator */
button:focus {
outline: none; /* Don't do this! */
}// Managing focus when opening modal
function openModal() {
const modal = document.getElementById('modal');
const firstFocusable = modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
modal.showModal();
firstFocusable?.focus();
}
// Return focus when closing
function closeModal(triggerElement) {
const modal = document.getElementById('modal');
modal.close();
triggerElement.focus();
}<!-- Custom interactive element -->
<div
role="button"
tabindex="0"
onkeydown="if(event.key === 'Enter' || event.key === ' ') handleClick(event)"
onclick="handleClick(event)"
>
Custom Button
</div><!-- Skip link at start of page -->
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<style>
.skip-link {
position: absolute;
left: -9999px;
}
.skip-link:focus {
left: 0;
top: 0;
z-index: 9999;
padding: 1rem;
background: #000;
color: #fff;
}
</style>
<main id="main-content" tabindex="-1">
<!-- Main content -->
</main>Press Tab to navigate through these elements. Notice the visible focus indicators.
Help others discover this tool!