The autofocus Attribute
The autofocus Attribute
Section titled “The autofocus Attribute”The autofocus attribute automatically focuses an element when the page loads or when a <dialog> element is shown. Only one element per page should have autofocus, and it should be used carefully to enhance (not disrupt) the user experience.
Syntax
Section titled “Syntax”<element autofocus>Content</element>Values
Section titled “Values”| Value | Description |
|---|---|
| Boolean (no value) | Element receives focus on page load |
Examples
Section titled “Examples”Basic Autofocus
Section titled “Basic Autofocus”Search Page Example
Section titled “Search Page Example”Dialog with Autofocus
Section titled “Dialog with Autofocus”Login Form
Section titled “Login Form”When to Use autofocus
Section titled “When to Use autofocus”Good Use Cases
Section titled “Good Use Cases”✓ Search pages: Primary purpose is searching ✓ Login forms: Speed up authentication ✓ Modal dialogs: Focus first input when dialog opens ✓ Single-purpose pages: One clear primary action ✓ Comment boxes: Streamline content creation
<!-- Search page - good use --><form action="/search"> <input type="search" name="q" autofocus placeholder="Search..."></form>
<!-- Login page - good use --><form action="/login"> <input type="text" name="username" autofocus placeholder="Username"> <input type="password" name="password" placeholder="Password"></form>When to Avoid
Section titled “When to Avoid”✗ Complex pages: Multiple competing elements ✗ Content pages: Users want to read, not type ✗ Accessibility concerns: May disorient users ✗ Forms in middle of page: Disrupts scrolling ✗ Mobile devices: Triggers keyboard automatically
<!-- Bad: Blog post with form at bottom --><article> <h1>Article Title</h1> <p>Long content...</p> <!-- DON'T autofocus here --> <form> <input type="text" autofocus placeholder="Comment"> </form></article>Best Practices
Section titled “Best Practices”1. Use Sparingly
Section titled “1. Use Sparingly”Only one element per page should have autofocus:
<!-- WRONG: Multiple autofocus attributes --><input type="text" autofocus><input type="email" autofocus>
<!-- RIGHT: Only one autofocus --><input type="text" autofocus><input type="email">2. Ensure Clear Purpose
Section titled “2. Ensure Clear Purpose”The page purpose should be obvious:
<!-- Clear search page --><body> <h1>Search</h1> <input type="search" autofocus></body>3. Consider User Context
Section titled “3. Consider User Context”Think about what users expect:
// Only autofocus on desktopif (window.innerWidth > 768) { document.getElementById('search').autofocus = true;}
// Or check if user came from link vs back buttonif (performance.navigation.type !== 2) { // Not a back button navigation searchInput.autofocus = true;}4. Respect User Preferences
Section titled “4. Respect User Preferences”// Check if user has interacted with pagelet userInteracted = false;document.addEventListener('click', () => userInteracted = true);document.addEventListener('keydown', () => userInteracted = true);
// Only autofocus if user hasn't interactedwindow.addEventListener('load', () => { if (!userInteracted) { document.getElementById('search').focus(); }});5. Provide Visual Feedback
Section titled “5. Provide Visual Feedback”Make sure focused elements are clearly visible:
input:focus { outline: 3px solid #3b82f6; outline-offset: 2px; /* Or custom focus style */ border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);}Accessibility Considerations
Section titled “Accessibility Considerations”Screen Readers
Section titled “Screen Readers”Autofocus can be disorienting for screen reader users:
- Interrupts screen reader from reading page content
- Jumps focus unexpectedly
- Skips context that comes before the focused element
Best practice: Add clear context:
<form aria-label="Search form"> <label for="search">Search:</label> <input type="search" id="search" autofocus aria-describedby="search-help"> <p id="search-help">Type to search products</p></form>Keyboard Users
Section titled “Keyboard Users”Power keyboard users may be typing when autofocus triggers:
// Delay autofocus slightly to avoid interruptingsetTimeout(() => { if (!document.activeElement || document.activeElement === document.body) { searchInput.focus(); }}, 100);Mobile Considerations
Section titled “Mobile Considerations”On mobile devices, autofocus:
- Triggers virtual keyboard automatically
- May scroll page to focused element
- Disrupts reading more severely on small screens
<!-- Consider mobile viewport --><meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Maybe skip autofocus on mobile --><input type="search" data-autofocus-desktop placeholder="Search">
<script> if (window.innerWidth > 768) { document.querySelector('[data-autofocus-desktop]').autofocus = true; }</script>JavaScript API
Section titled “JavaScript API”Setting Autofocus Dynamically
Section titled “Setting Autofocus Dynamically”const input = document.getElementById('myInput');
// Set autofocusinput.autofocus = true;input.setAttribute('autofocus', '');
// Check if element has autofocusif (input.autofocus) { console.log('Has autofocus');}
// Remove autofocusinput.autofocus = false;input.removeAttribute('autofocus');Programmatic Focus
Section titled “Programmatic Focus”Instead of autofocus, you can focus programmatically:
// Focus on page loadwindow.addEventListener('load', () => { document.getElementById('search').focus();});
// Focus when dialog opensfunction openDialog() { dialog.showModal(); dialog.querySelector('input').focus();}
// Focus after conditionif (errorOccurred) { errorInput.focus();}Focus with Selection
Section titled “Focus with Selection”// Focus and select all textconst input = document.getElementById('editField');input.focus();input.select();
// Or set cursor positioninput.focus();input.setSelectionRange(0, 0); // Startinput.setSelectionRange(input.value.length, input.value.length); // EndCommon Patterns
Section titled “Common Patterns”Conditional Autofocus
Section titled “Conditional Autofocus”// Only autofocus if coming from specific pageconst referrer = document.referrer;if (referrer.includes('homepage')) { searchInput.autofocus = true;}
// Only autofocus if no hash in URLif (!window.location.hash) { firstInput.autofocus = true;}Dialog Autofocus
Section titled “Dialog Autofocus”// Focus first input when dialog opensdialog.addEventListener('open', () => { const firstInput = dialog.querySelector('input'); if (firstInput) { firstInput.focus(); }});Form Validation
Section titled “Form Validation”// Focus first error fieldfunction validateForm() { const errors = [];
if (!nameInput.value) { errors.push(nameInput); } if (!emailInput.value) { errors.push(emailInput); }
if (errors.length > 0) { errors[0].focus(); return false; }
return true;}Common Pitfalls
Section titled “Common Pitfalls”Testing Autofocus
Section titled “Testing Autofocus”Manual Testing
Section titled “Manual Testing”- Load page: Verify correct element is focused
- Tab navigation: Ensure tab order makes sense
- Screen reader: Test with NVDA/JAWS/VoiceOver
- Mobile: Test on actual mobile devices
- Back button: Verify behavior when returning to page
Automated Testing
Section titled “Automated Testing”// Test with Jest/Testing Librarytest('search input has autofocus', () => { render(<SearchForm />); const input = screen.getByPlaceholderText('Search...'); expect(input).toHaveAttribute('autofocus');});
// Test focus actually movestest('input receives focus on load', () => { render(<SearchForm />); const input = screen.getByPlaceholderText('Search...'); expect(input).toHaveFocus();});Browser Support
Section titled “Browser Support”Universal support across all modern browsers:
| Browser | Support | Notes |
|---|---|---|
| Chrome | All versions | Full support |
| Firefox | 4+ | Full support |
| Safari | 5+ | Full support |
| Edge | All versions | Full support |
| Mobile | All versions | Triggers virtual keyboard |
Related Attributes
Section titled “Related Attributes”tabindex- Control focus orderaccesskey- Keyboard shortcuts to focus elementsdisabled- Prevent element from receiving focus