The autofill event is in origin trial

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:

  1. The autofill event handler executes just before the form field is autofilled.
  2. event.autofillValues provides 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.
  3. 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.
  4. 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:

  1. A personal information form which is similar to the example in this post, but goes beyond a basic demonstration of the autofill event.
  2. A credit card autofill demo which uses the autofill event 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.