Published: June 10, 2026
Forms are a frequent interaction point on the web, but they are responsible for a fair amount of friction for users. Browsers have long offered autofill capabilities to reduce this friction, saving users from repetitive tasks such as entering credit card numbers, addresses, and login credentials.
For developers, handling form autofills is a challenge. While developers can
listen for input or change events on <form> elements, these events don't
tell you how the data arrived in the field. This lack of clarity makes it
difficult to trigger specific logic—such as layout adjustments—at the exact
moment a form is autofilled. The new autofill
event—now
available as a Chrome origin trial
starting in Chrome 147—provides a useful signal for developers when the browser is assisting the user with autofill.
autofill: solving what input and change didn't
The input and change events are generic signals that don't differentiate
between the user manually filling out a form field and when autofill is used.
The lack of a dedicated event for autofilling forms makes it harder for
developers to reliably perform UI updates that are helpful when filling out
forms. For example, a user specifies their country of residence, and a nearby
field appears to specify the state or district they live in, which varies by
country. Triggering this update in response to an autofill request is more
predictable for developers and useful for users. The autofill event solves
this problem.
The autofill event executes just before the browser autofills a form. The
listener for the event receives an array of autofillValues to be filled and a
refill function. The listener can call the refill function to request that
the browser refills the form if, for example, the listener has changed the
content. Take this example form markup:
<form>
<div>
<label for="country">Country</label>
<select id="country" name="country" autocomplete="country">
<!-- ... -->
</select>
</div>
<div>
<label for="address-line-1">Address Line 1</label>
<input type="text" name="address-line-1" id="address-line-1" autocomplete="address-line1">
</div>
<div>
<label for="city">City</label>
<input type="text" name="city" id="city" autocomplete="address-level2">
</div>
<div>
<div class="state">
<!-- This section gets populated based on the
value provided in the country field -->
</div>
</div>
<div>
<input type="submit" value="Calculate">
</div>
</form>
This JavaScript binds the autofill event on the document:
document.addEventListener('autofill', async event => {
// A null check here is a good idea, as
// refills are not available in a WebView.
if (event.refill == null) {
/* Apply legacy logic */
return;
}
// Walk the fields
for (const {field, value} of event.autofillValues) {
if (field.name === 'country') {
if (value === 'Germany') {
document.querySelector('.state').innerHTML = `
<label for="state">State:</label>
<select name="state" id="state" autocomplete="address-level1">
<option selected="selected"></option>
<option value="BW">Baden-Württemberg</option>
<option value="BY">Bavaria</option>
<!-- Other states omitted -->
</select>
`;
} else {
/* Logic for other countries */
}
}
}
await event.refill();
});
This example is a typical address form. The user can click or tap in a form field to trigger an autofill tooltip. When an autofill address is selected, the following happens:
- The
autofillevent handler executes just before the form field is autofilled. event.autofillValuesprovides the proposed autofill data in an object with two properties:field: A reference to the DOM element to be autofilled.value: The proposed autofill value for the field.
- When the country field name is detected, logic detects the country—Germany in this example—and populates the state drop-down with the proper choices for the country.
event.refill()is called to instruct the browser to refill the form, which repeats the autofill action on the changed form.
If you are interested in more intricate autofill use cases, Yoav
Weiss of Shopify has created two demos:
- A personal information form
which is similar to the example in this post, but goes beyond a basic
demonstration of the
autofillevent. - A credit card autofill demo
which uses the
autofillevent to detect the card issuer and update the DOM substantially with rich visuals.
The credit card autofill demo is illustrative of the autofill event's
capabilities. While these types of experiences were possible before the
autofill event, having a dedicated event for form autofilling makes for a
better developer experience.
The autofill event and the :autofill CSS pseudo-class
The :autofill CSS
pseudo-class
matches autofilled form elements, and the autofill event can be a complement
to it.
For example, you might want to use :autofill to differentiate fields that were
just autofilled from those that were modified during the autofill event. This
could be a useful signal to the user that the field was prepopulated, but the
existence of the data in an editable form control tells the user they can still
change it if they need to.
document.addEventListener('autofill', async event => {
if (event.refill !== null) {
// Walk the fields to be autofilled:
for (const {field, value} of event.autofillValues) {
let cardIssuer;
// If this field is the credit card number,
// use its value to get the card issuer.
if (field.name === 'card-number') {
cardIssuer = getCardIssuerFromNumber(value);
}
// Populate the card issuer field with
// the data we got from the card number
if (field.name === 'card-issuer') {
field.value = cardIssuer;
field.classList.add('modified-by-event');
}
}
}
});
In the previous code block, the autofilled fields are walked until the credit
card number field is found. The data in the field is used to get the card's
issuer, which is populated into the field and given a class of
.modified-by-event. The autofill styling for this field can then be tweaked to
be distinct from other autofilled fields not modified by the autofill event:
/* Standard autofill style: */
input:autofill {
border: 0.25rem solid #cc0;
}
/* Autofill style for `autofill` event-modified data: */
input.modified-by-event-autofill:autofill {
border-color: #0cc;
}
With this, you can preserve styling semantics for autofilled form fields,
inherit :autofill styles, and still provide meaningful presentation to the
user that the form field has been autofilled in a distinct way.
The autofill event and the field-sizing CSS property
If the field-sizing CSS
property
has a value of content, fields like the <textarea> element automatically
resize to fit their contents. This eliminates the need for awkward scrollbars in
small fields:
textarea {
/* The field grows to fit the content automatically: */
field-sizing: content;
min-height: 3lh;
transition: min-height 0.2s ease-out;
}
It's a good user experience consideration, but it can cause layout shifts. As a
user types, the expansion of the input field is gradual. However, when a browser
autofills a multiline address into a <textarea> element, the field might
expand considerably in an instant. With the autofill event, you can manage
these transitions more effectively, for example, by animating the container or
adjusting its scroll position to avoid the user losing context.
document.addEventListener('autofill', event => {
// Assumes a single field for the purpose of a quick
// demonstration, such as a multiline address field:
const [addressDetails] = event.autofillValues;
// Since field-sizing: content causes an immediate jump,
// we can use the event to ensure the UI remains stable:
requestAnimationFrame(() => {
addressDetails.scrollIntoView({behavior: 'smooth', block: 'nearest'});
});
if (event.refill !== null) {
await event.refill();
}
});
Every application's requirements are different, so you need to figure out if
this is a pattern worth using—but this is illustrative of what is achievable
using a combination of CSS and the autofill event.
Detect and measure form autofills
Analytics data of form autofills is valuable for businesses, but measuring
autofills on
forms is
difficult with existing web features. For example, the practice is to rely on
the CSS :autofill pseudo-class, which is not Baseline.
The autofill event is a tool to detect form autofills. Because the event fires
only on an actual autofill attempt and not on any input, and the
event.autofillValues property contains only the fields that were autofilled,
you can track autofilled data:
document.addEventListener('autofill', event => {
// Get autofilled data
const autofillData = {
// Assumes the form has an ID for simplicity:
form: event.target.id,
autofilled: true
};
// Send to analytics endpoint
const body = JSON.stringify(autofillData);
navigator.sendBeacon('/analytics', body);
});
This example is simplified, but it shows how much simpler it is to capture this information. You can structure and collect autofill analytics data in a way that works for you, without workarounds that are difficult to implement and unreliable.
Register for the origin trial
The autofill event is in a Chrome origin trial, and your participation can
help Chrome make it better. Origin trials
let you test experimental features with real users and provide feedback to the
Chrome team before the API becomes a part of the web platform.
To start using the autofill event on your site, register for the
origin
trial
here. Chrome is looking forward to seeing how you use it, and
how that can help us find improvement opportunities.