- Success Criterion 2.1.2
- Conformance level A
Widget Where Tab Cycles Internally With No Way Out
2.1.2 — No Keyboard Trap
Scenario
Setting
A customer-support live-chat widget
What’s wrong
Focus loops inside a widget (calendar, editor, embedded iframe) where Tab cycles internally forever.
Example
<div class="chat-widget">
<div class="mini-calendar">
<!-- 42 day cells, each tabindex="0"; the last cell's Tab wraps back to the first -->
</div>
<textarea class="chat-input"></textarea>
</div> Why it matters
A customer tabbing through the calendar to pick an appointment date can never reach the chat input below it, so they can't ask a follow-up question.
How to test
Tab repeatedly inside a widget (calendar, rich editor, embedded iframe): if Tab cycles internally forever with no way to exit to the rest of the page, it fails.
How to fix
A widget's internal Tab loop should only cover its own controls; let the natural document order carry Tab onward once the last one is reached.
lastDayCell.addEventListener('keydown', (e) => {
if (e.key === 'Tab' && !e.shiftKey) {
e.preventDefault();
chatInput.focus();
}
}); Outcome
A customer moves through the calendar with Tab and lands right on the chat input to type their question.
Who is affected
Keyboard-only users get stuck cycling day cells and can't reach the rest of the widget.
Learn more
- Understanding Understanding document (opens in a new tab)
Related scenarios
- Keyboard Focus Stuck Inside an Embedded Plugin or Widget
- Modal Focus Trap With No Escape Key or Close Button
- Third-Party Embed That Captures and Never Releases Tab Focus
- Script That Yanks Focus Back Every Time the User Tabs Away
- Rich Text Editor That Captures Tab With No Documented Escape
- Autocomplete List That Keeps Recapturing Focus on Every Blur