Skip to content

The autofocus Attribute

Global 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.

<element autofocus>Content</element>
ValueDescription
Boolean (no value)Element receives focus on page load
Result
Result
Result
Result

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>

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>

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">

The page purpose should be obvious:

<!-- Clear search page -->
<body>
<h1>Search</h1>
<input type="search" autofocus>
</body>

Think about what users expect:

// Only autofocus on desktop
if (window.innerWidth > 768) {
document.getElementById('search').autofocus = true;
}
// Or check if user came from link vs back button
if (performance.navigation.type !== 2) {
// Not a back button navigation
searchInput.autofocus = true;
}
// Check if user has interacted with page
let userInteracted = false;
document.addEventListener('click', () => userInteracted = true);
document.addEventListener('keydown', () => userInteracted = true);
// Only autofocus if user hasn't interacted
window.addEventListener('load', () => {
if (!userInteracted) {
document.getElementById('search').focus();
}
});

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);
}

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>

Power keyboard users may be typing when autofocus triggers:

// Delay autofocus slightly to avoid interrupting
setTimeout(() => {
if (!document.activeElement || document.activeElement === document.body) {
searchInput.focus();
}
}, 100);

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>
const input = document.getElementById('myInput');
// Set autofocus
input.autofocus = true;
input.setAttribute('autofocus', '');
// Check if element has autofocus
if (input.autofocus) {
console.log('Has autofocus');
}
// Remove autofocus
input.autofocus = false;
input.removeAttribute('autofocus');

Instead of autofocus, you can focus programmatically:

// Focus on page load
window.addEventListener('load', () => {
document.getElementById('search').focus();
});
// Focus when dialog opens
function openDialog() {
dialog.showModal();
dialog.querySelector('input').focus();
}
// Focus after condition
if (errorOccurred) {
errorInput.focus();
}
// Focus and select all text
const input = document.getElementById('editField');
input.focus();
input.select();
// Or set cursor position
input.focus();
input.setSelectionRange(0, 0); // Start
input.setSelectionRange(input.value.length, input.value.length); // End
// Only autofocus if coming from specific page
const referrer = document.referrer;
if (referrer.includes('homepage')) {
searchInput.autofocus = true;
}
// Only autofocus if no hash in URL
if (!window.location.hash) {
firstInput.autofocus = true;
}
// Focus first input when dialog opens
dialog.addEventListener('open', () => {
const firstInput = dialog.querySelector('input');
if (firstInput) {
firstInput.focus();
}
});
// Focus first error field
function 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;
}
  1. Load page: Verify correct element is focused
  2. Tab navigation: Ensure tab order makes sense
  3. Screen reader: Test with NVDA/JAWS/VoiceOver
  4. Mobile: Test on actual mobile devices
  5. Back button: Verify behavior when returning to page
// Test with Jest/Testing Library
test('search input has autofocus', () => {
render(<SearchForm />);
const input = screen.getByPlaceholderText('Search...');
expect(input).toHaveAttribute('autofocus');
});
// Test focus actually moves
test('input receives focus on load', () => {
render(<SearchForm />);
const input = screen.getByPlaceholderText('Search...');
expect(input).toHaveFocus();
});

Universal support across all modern browsers:

BrowserSupportNotes
ChromeAll versionsFull support
Firefox4+Full support
Safari5+Full support
EdgeAll versionsFull support
MobileAll versionsTriggers virtual keyboard
  • tabindex - Control focus order
  • accesskey - Keyboard shortcuts to focus elements
  • disabled - Prevent element from receiving focus