惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Engineering at Meta
Engineering at Meta
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
博客园_首页
云风的 BLOG
云风的 BLOG
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
博客园 - Franky
Cyberwarzone
Cyberwarzone
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cisco Blogs
T
Tailwind CSS Blog
Project Zero
Project Zero
博客园 - 叶小钗
S
SegmentFault 最新的问题
K
Kaspersky official blog
B
Blog
T
The Exploit Database - CXSecurity.com
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
G
Google Developers Blog
Security Latest
Security Latest
T
Tenable Blog
V
Vulnerabilities – Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
H
Help Net Security
T
Threat Research - Cisco Blogs
美团技术团队
AWS News Blog
AWS News Blog
P
Proofpoint News Feed
F
Fortinet All Blogs
NISL@THU
NISL@THU
大猫的无限游戏
大猫的无限游戏
The Last Watchdog
The Last Watchdog
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
D
DataBreaches.Net

Aaron Gustafson: Latest Posts & Links

LLM biased against accessible code (Claude Code issue #56079) :: Aaron Gustafson Can Your AI Pass the Accessibility Test? :: Aaron Gustafson Can Your AI Pass the Accessibility Test? :: Aaron Gustafson Fixing Accessibility After the Fact Is Too Late :: Aaron Gustafson Easy Data-entry Verification with a Web Component :: Aaron Gustafson Artificial Intelligence Has One Chance To Get Accessibility Right :: Aaron Gustafson Building a general-purpose accessibility agent—and what we learned in the process :: Aaron Gustafson Fixing Accessibility After the Fact Is Too Late :: Aaron Gustafson AI companies will fail. We can salvage something from the wreckage :: Aaron Gustafson Accessible faux-nested interactive controls :: Aaron Gustafson AI-assisted coding transforms PDF to web app using NYS Design System :: Aaron Gustafson Modern CSS Feature Support For Shadow DOM :: Aaron Gustafson AI is locking people out. At Scale. :: Aaron Gustafson The Incredible Overcomplexity of the Shadcn Radio Button :: Aaron Gustafson Accessibility in the End of Deterministic Design (Again) :: Aaron Gustafson Making keyboard navigation effortless :: Aaron Gustafson The WebAIM Million: The 2026 report on the accessibility of the top 1,000,000 home pages :: Aaron Gustafson Under the hood of MDN’s new frontend :: Aaron Gustafson Endgame for the Open Web :: Aaron Gustafson slideVars :: Aaron Gustafson AI is accidently making documentation accessible :: Aaron Gustafson Design systems can’t automate away all of your accessibility considerations :: Aaron Gustafson The Power of ‘No’ in Internet Standards :: Aaron Gustafson Nice Select :: Aaron Gustafson Visual Validation Feedback for Form Fields :: Aaron Gustafson Different contexts, different tools, same person :: Aaron Gustafson Accessibility Assistant for Figma v52 :: Aaron Gustafson Some blind fans to experience Super Bowl with tactile device that tracks ball :: Aaron Gustafson Why we teach our students progressive enhancement :: Aaron Gustafson Repeatable Form Fields Made Simple :: Aaron Gustafson A Production-Ready Web Component Starter Template :: Aaron Gustafson Fullscreen Video and Iframes Made Easy :: Aaron Gustafson Dynamic Datalist: Autocomplete from an API :: Aaron Gustafson Lazy Loading Images Based on Screen Size :: Aaron Gustafson A Web Component for Obfuscating Form Fields :: Aaron Gustafson Forrester Research: As technology has evolved, so has the need for accessibility :: Aaron Gustafson Creating a more accessible web with ARIA Notify :: Aaron Gustafson Optimizing Your Codebase for AI Coding Agents :: Aaron Gustafson A Web Component for Conditionally Displaying Fields :: Aaron Gustafson Default Isn’t Design :: Aaron Gustafson Identifying Accessibility Data Gaps in CodeGen Models :: Aaron Gustafson Designing for Distress: Understanding Users in Crisis :: Aaron Gustafson Why I'm Betting Against AI Agents in 2025 (Despite Building Them) :: Aaron Gustafson Why AI Won’t Destroy Us with Microsoft’s Brad Smith :: Aaron Gustafson Learning Web Design, 6th Edition is out! :: Aaron Gustafson
Never Lose Form Progress Again :: Aaron Gustafson
Aaron Gustafson · 2026-04-21 · via Aaron Gustafson: Latest Posts & Links

Few things are more annoying than losing your progress halfway through a form. Maybe the browser crashes. Maybe the tab gets closed. Maybe your kid yells from the other room and you come back three hours later wondering why you ever thought now was a good time to fill out a mortgage application. Whatever the cause, form-saver makes those interruptions a lot less obnoxious. Which is nice, because forms are usually annoying enough on their own.

At its core, form-saver is a small web component that wraps a form, keeps an eye on it, stores values in localStorage, and restores them when the page loads again. Better yet, it clears out saved data after a successful submission so you’re not accidentally resurrecting stale information the next time someone stops by. Nobody wants yesterday’s half-finished support request shambling back to life.

Basic usage

All you need to do is wrap your form in the component:

<form-saver>
  <form action="/contact" method="post">
    <label>
      Name
      <input name="name" autocomplete="name" />
    </label>
    <label>
      Email
      <input name="email" type="email" autocomplete="email" />
    </label>
    <label>
      Message
      <textarea name="message"></textarea>
    </label>
    <button type="submit">Send</button>
  </form>
</form-saver>

That’s it. The component targets the first descendant form, saves values as users type or make changes, and restores them when they come back. No extra plumbing. Just a form with a slightly better memory than most of us have before coffee — depending on the day, that may not be a terribly high bar, but still.

This is especially handy for forms that are a little more involved than a simple email signup. Job applications, checkout flows, support requests, and multi-question onboarding forms all benefit from a little resilience. So do the people filling them out, who generally have better things to do than retype the same answers because a tab got squirrelly.

What actually gets saved?

form-saver supports the controls most of us reach for every day:

  • Text-style input fields
  • textarea elements,
  • select elements (including multi-selects), and
  • checkbox and radio controls.

File inputs are intentionally excluded.

Because the component works in light DOM, your form remains your form. Your labels, validation, layout, and CSS continue to work exactly as they did before. form-saver just adds a bit of memory and, ideally, cuts down on a few muttered curses.

Want to keep a few fields after submit?

In many cases, clearing everything after a successful submission is the right call. Sometimes, though, it makes sense to keep a few details around. Maybe you want to preserve a visitor’s name and email address on a contact form while clearing the message body. That way they do not have to keep retyping the boring bits. Nobody wakes up excited to enter their email address for the fourth time.

That is what the retain attribute is for:

<form-saver retain="name email">
  <form action="/contact" method="post"></form>
</form-saver>

After a successful submission, name and email stick around, but message gets cleared. Simple, sensible, and less likely to leave someone staring at your form like it just betrayed them personally.

Better yet, let users decide

Persisting form data can be incredibly helpful, but there is a human side to this too. Just because we can keep someone’s information around does not necessarily mean we should do it without asking. That is where retain-choice comes in. It lets you be useful without getting presumptuous.

Add it alongside retain and form-saver will inject an opt-in checkbox for the user. Nice and easy:

<form-saver
  retain="name email"
  retain-choice
  retain-choice-label="Store my contact information for later"
>
  <form action="/contact" method="post"></form>
</form-saver>

By default, that checkbox is inserted just before the first submit control. If the user leaves it unchecked, the retained fields are cleared along with everything else after submit. If they opt in, those selected fields remain. Their call, as it should be. Gotta love a little informed consent.

Need to place that control somewhere more appropriate in your layout? Use retain-choice-container to point to a CSS selector:

<form-saver
  retain="name email"
  retain-choice
  retain-choice-label="Remember my details next time"
  retain-choice-container=".form-footer"
>
  <form action="/contact" method="post"><div class="form-footer">
      <button type="submit">Send</button>
    </div>
  </form>
</form-saver>

That gives you a lot more control over the experience without making you build the retention UI yourself.

Need a custom storage key?

By default, form-saver derives its storage key from the wrapped form’s method and action, which is usually exactly what you want. It keeps different forms from stepping on one another and keeps the setup nice and boring. Boring is good.

If you need something more explicit, you can provide your own storage-key:

<form-saver storage-key="checkout:shipping-address">
  <form action="/checkout/shipping" method="post">
    <label>
      Street Address
      <input name="street-address" autocomplete="street-address" />
    </label>
    <label>
      Postal Code
      <input name="postal-code" autocomplete="postal-code" />
    </label>
    <button type="submit">Continue</button>
  </form>
</form-saver>

This is useful when a form’s URL is not stable or when you want multiple views to intentionally share the same saved state. Sometimes explicit is just easier. Sometimes it is the only way to stay sane.

Want to drive it yourself?

If you need more direct control, the component exposes a few methods:

const saver = document.querySelector("form-saver");

// Persist the current state
saver.saveFormState();

// Restore previously saved values
saver.restoreFormState();

// Clear out anything stored for this form
saver.clearSavedData();

That can be useful when you want to pair it with your own UI, analytics, or some custom workflow around save and restore. Or when you just like being the one driving and do not fully trust anything labeled “automatic.”

Progressive enhancement, as usual

This component follows a pattern I am always going to favor: start with a perfectly ordinary form, then layer on the enhancement. If JavaScript fails, the form still works. Users can still fill it out and submit it. They just will not get the recovery behavior. Annoying, perhaps, but not catastrophic. And that is very much the point.

That’s a pretty good trade-off.

And because saved values are only cleared after a successful submit flow, you do not lose everything just because client-side validation blocked submission or some other script got clever at exactly the wrong moment. That matters. A lot of “smart” form experiences are only smart right up until they are not.

Demo

If you want to kick the tires, I put together a live demo with examples of the retention options as well:

Grab it

The project is available on GitHub, and you can install it from npm:

npm install @aarongustafson/form-saver

If you want the easiest path, just import it and let the component register itself:

import "@aarongustafson/form-saver";

If you would rather define it yourself, you can import the class directly:

import { FormSaverElement } from "@aarongustafson/form-saver/form-saver.js";

customElements.define("form-saver", FormSaverElement);

Either way, you wind up with a more forgiving form experience and a little less needless frustration for the people filling it out. Which, in my book, is a pretty solid deal. The bar for delight in forms is often just “don’t make me do that again,” and honestly, I’ll take it.