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

推荐订阅源

Jina AI
Jina AI
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
H
Help Net Security
Attack and Defense Labs
Attack and Defense Labs
The GitHub Blog
The GitHub Blog
L
LINUX DO - 最新话题
A
Arctic Wolf
博客园_首页
S
Securelist
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
Cyberwarzone
Cyberwarzone
小众软件
小众软件
T
Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Blog — PlanetScale
Blog — PlanetScale
N
News and Events Feed by Topic
NISL@THU
NISL@THU
Forbes - Security
Forbes - Security
博客园 - 聂微东
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
H
Heimdal Security Blog
罗磊的独立博客
S
Security @ Cisco Blogs
B
Blog
T
Troy Hunt's Blog
Engineering at Meta
Engineering at Meta
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
Hacker News - Newest:
Hacker News - Newest: "LLM"
I
Intezer
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA
The Cloudflare Blog
S
Schneier on Security
月光博客
月光博客
L
LINUX DO - 热门话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org

Adactio

June 16th, 2026, 11:12am June 16th, 2026, 10:16am Enhancing with CSS Grid Lanes How building an HTML-first site doubled our users overnight Speaking in Dublin June 13th, 2026, 9:09pm A tale of two browsers Sarah Canary by Karen Joy Fowler June 12th, 2026, 5:59pm The Field Guide to CSS Grid Lanes June 12th, 2026, 12:24pm June 12th, 2026, 8:58am June 11th, 2026, 6:22pm June 11th, 2026, 6:20pm June 10th, 2026, 6:25pm June 10th, 2026, 10:14am June 9th, 2026, 8:50pm June 9th, 2026, 1:55pm June 8th, 2026, 7:45pm June 8th, 2026, 4:32pm Amsterdamming June 5th, 2026, 3:16pm June 4th, 2026, 8:21pm June 2nd, 2026, 8:37pm 25 years of The Session Happy Monday everyone, and let's talk about gender and ethnicity ratios at tech events. AI and the Rise of Mediocrity May 28th, 2026, 7:24pm Picture at an exhibition May 27th, 2026, 9:41pm May 27th, 2026, 1:52pm May 25th, 2026, 8:03pm Gaeltacht cois Tamaise 2026 May 25th, 2026, 3:07pm May 23rd, 2026, 8:06pm May 23rd, 2026, 8:31am May 22nd, 2026, 3:38pm May 22nd, 2026, 8:19am May 22nd, 2026, 7:22am May 21st, 2026, 8:19pm Brigid by Kim Curran May 20th, 2026, 7:12pm The value is in the difficulty - Annotated May 17th, 2026, 6:21pm May 15th, 2026, 4:19pm Tito as Gaeilge The closing talks at UX London 2026 Three things about data Native Apps Should Be Avoided Whenever Possible — No One's Happy WebKit Features for Safari 26.5 May 11th, 2026, 4:17pm I knew my writing students were using AI. Their confessions led to a powerful teaching moment | Micah Nathan Gideon The Ninth by Tamsyn Muir May 8th, 2026, 3:55pm Better Browser Caching with No-Vary-Search May 7th, 2026, 9:55am May 7th, 2026, 7:49am The schedule for UX London 2026 Google’s Prompt API Reminder: You Can Stitch Together Lots of Little HTML Pages With Navigations For Interactions Netizen | Derek Sivers April 30th, 2026, 7:59pm April 29th, 2026, 8:12pm April 27th, 2026, 7:47pm April 25th, 2026, 12:03pm April 25th, 2026, 12:00pm April 25th, 2026, 8:03am April 24th, 2026, 7:57pm April 24th, 2026, 5:12pm Summary punishment It's Not AI. It's FOMOnetization. Alistair Davidson / validation-enhancer · GitLab Never Lose Form Progress Again :: Aaron Gustafson Dilation Expansion artifacts April 19th, 2026, 6:03pm Finn Mac Cool by Morgan Llywelyn April 17th, 2026, 7:58am April 16th, 2026, 6:42pm Threat models No-stack web development Design and Engineering, As One · Matthias Ott April 14th, 2026, 7:21am April 13th, 2026, 7:47pm April 11th, 2026, 8:39am April 10th, 2026, 5:36pm My salary history Conference organising in 2026 April 7th, 2026, 8:32pm TinyStart AI Might Be Our Best Shot At Taking Back The Open Web | Techdirt April 6th, 2026, 12:46pm The AI Great Leap Forward April 4th, 2026, 6:42pm April 3rd, 2026, 5:27pm April 2nd, 2026, 8:58pm April 2nd, 2026, 4:32pm Web Day Out - 12 March 2026 Mistrust HTML Video Poster Image: Enable Responsive Images and ALT Text for Poster
Two Paradigms for Enhancing HTML Tags
Jared White · 2026-04-25 · via Adactio

  Permalink

Before I describe the two different paradigms for enhancing HTML tags, let’s first explain what it means to enhance an HTML tag.

I’ll use the <form> tag as an example, since I’ll be showcasing a couple of real-world form enhancements below.

So, let’s say you have a <form> element which has been instantiated as an object in your Document Object Model (DOM) as part of the HTML deserialization process (aka the markup is parsed, turned into DOM, and rendered to screen).

At the moment the form element is instantiated and connected to the document, you want to enhance the form by adding two features:

  • You want to display some fancy visual validation feedback (e.g., red text below a blank field saying “Please enter your name”, etc.).
  • You want to autosave form fields so if the browser session is interrupted, the user can load the form back up and continue from where they left off.

These enhancements are accomplished by executing JavaScript which sets up a reference to the form, adds event listeners, perhaps modifies the DOM to render some additional content, and exerts a degree of control over the lifecycle of the form.

The question then becomes, how do you set up this JavaScript? How does a wad of code get spun up in a 1:1 relationship with the element to be enhanced?

There is a bad way, and two good ways.

❌ First, the bad way:

<form id="some-form">
  ...
</form>

<script>
  const someForm = document.querySelector("#some-form")
  // do stuff with the form
</script>

(In the past, this would have likely been written using jQuery APIs, but the principle is the same.)

The reason this is bad is because you are brute-forcing the execution of the code in an imperative way, rather than using a declarative technique to execute the code whenever the relevant tag shows up. First of all, you likely want this code living in a tree of JS files somewhere else, rather than in a script tag next to the form. You might want the code to apply to various sorts of forms, not just one form with a particular ID. And why even use an ID at all (which is a fragile technique)? Plus this technique will completely break at any time you use reactivity or hypermedia: what if the form comes in via a fragment after the page has loaded? Will your code know that an ajax fragment has suddenly resulted in a DOM update?

The year is 2026…we have much better ways of accomplishing our goal!

Let’s look at the two good enhancement paradigms.

✅ I’ll pseudocode the first one, because there’s not yet a vanilla web API to make it work. Essentially, this paradigm is based on using a MutationObserver to look for a magic attribute on any element, and then inspecting that attribute in order to determine how to execute the relevant JS code to enhance the element. For example:

<form add-enhancements="validate autosave">
  ...
</form>

As soon as this form is instantiated, the observer will look for add-enhancements, parse the attribute into two terms: validate and autosave, and then based on a registry of available enhancements, run those two enhancements by passing along the form element so the enhancements can perform their tasks.

You may have previously used real-world solutions which operate on this principle, for example Hotwired Stimulus with its “controllers” concept. A web-native version of this would be the concept of custom attributes. They might work in a similar manner to custom elements, only instead of a 1:1 relationship between a custom HTML tag and JS element code running in a subclass of HTMLElement, there’d be a 1:n relationship: one tag could be enhanced by any number of bits of code via custom attribute lifecycles, and the tag itself would not be a custom subclass of HTMLElement but could be literally anything, even a standard form.

I think that would be a fantastic API, but I don’t believe there’s any immediate effort to implement it in browsers. Thus userland solutions will need to be used for these use cases.

✅ The second enhancement paradigm comes to us via that good ol’ web API we already know and love: web components.

Or perhaps more specifically, HTML Web Components as they’ve come to be called. These are custom elements which don’t really exist to serve as “components” in the design system UI sense of the word, but are there to enhance HTML which already exists.

Here are a couple of real-world form enhancements using this paradigm, which would be used in the markup like this:

<validation-enhancer>
  <form-saver>
    <form>
      ...
    </form>
  </form-saver>
</validation-enhancer>

This is a type of enhancement via element composition. By layering the form within one or more parent custom elements, you can modify the behavior of the form and add new features. This works in production today thanks to a couple of new libraries:

I think it’s fascinating that both of these projects launched just in the past few weeks, tackling totally different form problems but using the same paradigm of enhancement. While there are very specific cases where HTML web components aren’t a great solution (for example, you can’t insert custom elements inside of table markup, thus you’d have to wrap an entire table rather than any specific rows or columns), for the most part this is a tried-and-true way of authoring enhancements using vanilla web APIs.

I love seeing stuff like this! It would be awesome to see a lot more folks writing enhancements in this manner—at least until we do get a custom attributes API.


But…what about is=? Inevitably when this conversation comes up in discussions of web components’ capabilities, certain people will bring up the is= attribute and take a dump on Safari for nixing it. is= would let you write something like:

<form is="form-saver">
  ...
</form>

And then you could literally write a subclass of HTMLFormElement as a custom element which would get instantiated in this case.

Two major problems with this idea, and why I have always agreed with the WebKit team for nixing it:

  • It creates a dangerous coupling between the implementation details of specific types of elements and their userland subclasses. Suddenly, you’re not just subclassing HTMLElement which is an abstract superclass, you’re subclassing forms and buttons and video players and who knows what. There are a wide variety of headaches around future compatibility and breakage in such a scenario.
  • An even bigger issue in my opinion: You can only do this once! Duh.

In the above example, we might have used is="form-saver" to add autosave functionality to the form, but what if you also wanted the enhanced validation behavior? ❌ Too bad! 👎 You can’t add multiple terms to the is attribute because JavaScript doesn’t allow multiple inheritance. In other words, that form simply can’t be instantiated based on two or more class definitions. Just not how OOP works on the web or in JavaScript.

What we really need is the ability to enhance any existing HTML tag with an arbitrary number of enhancements. That’s why a proposed API like custom attributes, or today’s composition via multiple parent custom elements, are far preferable solutions than the is attribute and its limited direct inheritance.