Standardizing WebKit’s Autofill Pseudo-Class

The CSS :-webkit-autofill pseudo-class has been a long-standing tool for styling browser-autofilled form fields in Chrome, Safari, and most other modern browsers. Its usefulness extends beyond pure aesthetics — developers also use it to detect which fields have been autofilled via JavaScript.

While there is no standard autofill-specific event, developers can listen on the form’s input event and then check the pseudo-class state of individual fields. Now, however, the HTML Standard has formally added the :autofill pseudo-class, with :-webkit-autofill retained as an alias. The CSS Selectors module will also adopt this pseudo-class.

The :autofill and :-webkit-autofill pseudo-classes must match <input> elements that have been autofilled by the user agent. These pseudo-classes must stop matching if the user edits the autofilled field.

Both forms have now been implemented in Firefox, with the feature expected to ship in Firefox 86.

let autofilled = document.querySelectorAll(":-webkit-autofill");

Grid Offers an Alternative to Spacer Elements

There’s an ongoing debate about how to handle spacing between elements like icons and text inside buttons. One approach is a dedicated spacer <span> element, which lets neither the icon nor the text “own” the space. But CSS Grid offers a cleaner alternative: applying display: grid to the button and using the gap property directly on the container.

That pattern also solves a real-world issue found in CSS-Tricks’s newsletter link markup, where two &nbsp; entities are used to push an emoji and text apart. Replacing that with a two-column grid plus a gap value gives far more precise and maintainable spacing.

Cursor Pointer Conventions Under Discussion

Browser defaults aren’t always what users expect. CSS UI Level 4 defines cursor: pointer alongside specific guidance: user agents must apply it to hyperlinks, and authors may use it on other interactive elements. Yet websites like Wikipedia apply the pointer cursor far more broadly — to buttons, checkboxes, and other clickable controls — reflecting a common divergence from default browser behavior.

The cursor is a pointer that indicates a link. … User agents must apply cursor: pointer to hyperlinks. … Authors should use pointer on links and may use on other interactive elements.

One element where the pointer arguably makes particular sense is <summary>, the disclosure toggle within a <details> element. Since that entire region is interactive, developers often want a visual cue beyond the standard text cursor.

Autoplay Videos Wait for Visibility

Muted, inline autoplay video became popular as a substitute for animated GIFs, in part because modern video codecs are far more energy-efficient than GIF’s legacy format. But this only works well if those videos pause when they scroll off-screen.

Developers have traditionally used Intersection Observer for such visibility pausing. That may be redundant now: all major browsers except Firefox automatically delay <video muted autoplay> until the video is actually visible — such as when it scrolls into the viewport or becomes visible through CSS or DOM insertion.

<video autoplay> elements will only begin playing when visible on-screen such as when they are scrolled into the viewport, made visible through CSS, and inserted into the DOM.

<!-- a basic re-implementation of a GIF using <video> -->
<video autoplay loop muted playsinline src="meme.mp4"></video>

New @font-face Descriptors for Metric Control

Font metrics vary from system to system, and those differences become obvious in large headings or when a webfont swaps with its fallback during page load. A mismatch can cause jarring layout shift as soon as the real font arrives and replaces the fallback.

Chrome has now added three CSS @font-face descriptors that override the default metric defaults of a font:

  • ascent-override — for the height above the baseline
  • descent-override — for the depth below the baseline
  • line-gap-override
@font-face {
  font-family: Roboto;
  /* Merriweather Sans has 125.875px ascent 
   * and 35px descent at 128px font size.
   */
  ascent-override: calc(125.875 / 128 * 100%);
  descent-override: calc(35 / 128 * 100%);
  src: local(Roboto-Regular);
}