JavaScript focus and blur Events
Learn how the JavaScript focus and blur events work, how they differ from focusin and focusout, and how to use them for form validation and focus management.
JavaScript gives you fine-grained control over which element is currently focused — the element that receives keyboard input. The focus and blur events let you react the moment an element gains or loses focus, which is the foundation for inline form validation, highlighting the active field, building keyboard-friendly widgets, and guiding users through a form. This article covers what the events are, how they differ from their bubbling cousins focusin/focusout, and several practical patterns.
This page builds on the introduction to browser events. If you need to handle events on many elements at once, also read about bubbling and capturing.
Understanding Focus and Blur in JavaScript
The focus event fires when an element becomes the active target of keyboard input — the element that document.activeElement points to. The blur event fires when that element loses focus, for example because the user clicks elsewhere, presses Tab, or focus is moved programmatically.
By default only interactive elements can be focused: links (<a href>), form controls (<input>, <textarea>, <select>, <button>), and a few others. To make any element focusable — a <div>, <span>, or <li> — give it a tabindex attribute. Use tabindex="0" to put it in the natural tab order, or tabindex="-1" to make it focusable only via script (element.focus()).
A critical gotcha: focus and blur do not bubble. A listener attached to a parent element will not fire when a descendant input gains focus. When you need event delegation on a container, use the bubbling counterparts focusin and focusout instead — they behave identically but propagate up the DOM tree.
Focus vs. Blur vs. Focusin vs. Focusout
| Event | Fires when | Bubbles? |
|---|---|---|
focus | element gains focus | No |
blur | element loses focus | No |
focusin | element gains focus | Yes |
focusout | element loses focus | Yes |
For a single, known element, focus/blur are simplest. For a whole form or a list of fields, attach focusin/focusout once on the container.
How to Implement Focus Events
To use the focus event, attach a listener to the element. The example below highlights an input the moment it gains focus:
<input type="text" id="nameInput" placeholder="Enter Your Name">
<script>
document.getElementById('nameInput').addEventListener('focus', function(event) {
event.target.style.backgroundColor = 'lightblue';
});
</script>This code snippet makes the background of the input field light blue when it is focused, enhancing the user interface by indicating where the user is currently typing. For simple styling, consider using the CSS `:focus` pseudo-class as a standard non-JavaScript alternative:
input:focus {
background-color: lightblue;
}How to Implement Blur Events
Validating on blur is one of the most common uses of these events: you let the user finish typing, then check the value when they move away from the field. Here's how to validate an email address when the input loses focus:
<input type="email" id="emailInput" placeholder="Enter Your Email">
<script>
document.getElementById('emailInput').addEventListener('blur', function(event) {
// Simplified regex for educational purposes
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(event.target.value)) {
alert('Please enter a valid email address.');
event.target.style.backgroundColor = 'salmon';
} else {
event.target.style.backgroundColor = 'lightgreen';
}
});
</script>This script checks if the entered email matches a standard email format and alerts the user if the input is invalid. The background color changes to green if valid and salmon if not, providing immediate visual feedback.
Focusing Elements with Script
Beyond reacting to events, you can move focus yourself with element.focus() and remove it with element.blur(). This is useful for sending the cursor to the first field on page load, or returning focus to an invalid field after validation.
<input id="search" placeholder="Search..." />
<button id="go">Focus the search box</button>
<script>
document.getElementById('go').addEventListener('click', () => {
document.getElementById('search').focus();
});
</script>Two helpful extras:
document.activeElementalways returns the element that currently has focus (or<body>if none does). It's handy for checking focus state without listeners.focus({ preventScroll: true })focuses an element without scrolling it into view — useful when you manage scrolling yourself.
For a field that should be focused as soon as the page loads, the HTML autofocus attribute (<input autofocus>) is the declarative, no-JavaScript option.
Using focusin/focusout for Delegation
Because focus and blur don't bubble, attaching one listener to a form won't catch focus changes on its inputs. The bubbling focusin/focusout events solve this — you handle every field from a single parent listener:
<form id="signup">
<input name="email" placeholder="Email" />
<input name="password" type="password" placeholder="Password" />
</form>
<script>
const form = document.getElementById('signup');
form.addEventListener('focusin', (event) => {
event.target.style.outline = '2px solid royalblue';
});
form.addEventListener('focusout', (event) => {
event.target.style.outline = '';
});
</script>The focusout event also exposes event.relatedTarget — the element receiving focus next — which lets you tell where focus is going.
Advanced Techniques: Managing Multiple Fields
When a user completes a form field correctly, you can automatically shift focus to the next input upon blurring the current field. This streamlines form completion by eliminating the need for manual clicks. Here is how to implement this behavior:
<input type="text" id="firstName" placeholder="First Name" />
<input type="text" id="lastName" placeholder="Last Name" />
<div id="error" style="color: red;"></div> <!-- Display error message here -->
<script>
document.getElementById('firstName').addEventListener('blur', validateFirstName);
function validateFirstName(event) {
const input = event.target;
const errorDiv = document.getElementById('error');
// Allow only letters and spaces, must not be empty
const nameRegex = /^[A-Za-z ]+$/;
if (!nameRegex.test(input.value)) {
errorDiv.textContent = 'Please enter a valid first name.'; // Display error message
input.style.backgroundColor = 'salmon'; // Set background to salmon on invalid input
input.focus(); // Keep focus on the first name input to encourage correction
} else {
input.style.backgroundColor = 'white'; // Reset background to white on valid input
errorDiv.textContent = ''; // Clear error message
document.getElementById('lastName').focus(); // Optionally move focus to the last name input
}
}
</script>This example automatically shifts focus to the lastName input field once a valid first name is entered, enhancing user experience by reducing the need for manual clicks.
Calling
input.focus()from inside ablurhandler can fight the user. If they were trying to click a different element, refocusing the field can feel like a trap. Use this pattern sparingly, and prefer showing an error message that the user can fix at their own pace.
Common Pitfalls
- Don't expect
focus/blurto bubble. A container listener forfocuswill never fire; switch tofocusin/focusoutfor delegation. blurruns before the click on another control completes. If ablurhandler hides or removes an element the user just clicked, the click may not register — checkevent.relatedTargetfirst.- Hidden or
display:noneelements can't be focused.element.focus()silently does nothing on them. - Forcing focus hurts accessibility when it's unexpected. Keep the keyboard tab order predictable and avoid trapping focus.
- For purely visual focus styling, prefer the CSS
:focus/:focus-visiblepseudo-classes over JavaScript — they require no listeners and survive keyboard-only interaction.
Conclusion
Focus and blur events are the backbone of interactive, accessible forms. Knowing that focus/blur don't bubble (and that focusin/focusout do), how to move focus with element.focus(), and where to draw the line between JavaScript and the CSS :focus pseudo-class lets you build responsive input experiences without surprising your users.
Next, explore related browser interactions: keyboard events, the change, input, cut, copy, paste events, and bubbling and capturing for delegation.