Use TagAction when you want plain semantic HTML to behave the way people expect (sortable tables, copy buttons on code, dialogs that open from a button) with one script tag, no classes, and no page script.
<script src="https://cdn.jsdelivr.net/npm/tagaction@0/tagaction.min.js" defer></script>TagAction is the companion to TagBrush.css, the classless stylesheet. TagBrush makes HTML look finished; TagAction makes it act finished. Each works without the other, and they look best together.
- Progressive enhancement. Every page works with JavaScript off. TagAction only adds behavior.
- No new syntax. It keys off native elements and attributes first, then ARIA attributes, then a few
data-tag-*attributes. No classes, no templating, no components, no reactive state. - Fills gaps, doesn't replace the browser. Native
<details>,<dialog>,popover, andcommandfordo their own work. - Works with htmx and anything else. Content added after load is enhanced automatically.
- Small. One file, no dependencies, about 7 KB gzipped.
| HTML | Behavior | Hook |
|---|---|---|
<dialog> |
A modal closes on a backdrop click. Opens from a button with no script. | native commandfor / command; closedby opts out |
<details> |
One open at a time; remembers open state | native name; data-tag-remember |
<table> |
Click a header to sort; filter from a search box | <thead>; aria-sort; <input aria-controls> |
<form> |
Messages under the fields; busy submit button; unsaved-changes warning | native validation; method="post" |
<textarea> |
Grows as you type; character counter | no rows; maxlength |
<input type="file"> |
Lists chosen files; drag and drop | multiple; its <label> |
<input type="password"> |
Show/Hide button | automatic |
<pre> |
Copy button | automatic |
<time> |
Reader's timezone; "3 hours ago" | datetime with a zone; data-tag-time="relative" |
<nav>, <a> |
aria-current="page"; follows the scroll in a table of contents |
automatic |
<h2>, <h3> |
"#" links; generated table of contents | id; <nav data-tag-toc> |
<img> |
Click to enlarge | a link to an image file; a shrunk image in <figure> |
<menu>, dropdowns |
Arrow keys, Escape, click outside | <button aria-expanded aria-controls>; popover menus |
<output> |
Live value or total | native for |
<abbr> |
Title shown on tap | title |
<template> |
Add repeated rows | <button commandfor command="--clone"> |
llms.txt has the exact HTML for each one. It is the short, complete guide, written for people and for AI agents.
A modal with no script:
<button commandfor="confirm" command="show-modal">Delete</button>
<dialog id="confirm">
<form method="dialog">
<p>Delete this file?</p>
<button value="cancel">Cancel</button>
<button value="ok">Delete</button>
</form>
</dialog>A table you can sort and filter:
<input type="search" aria-label="Filter orders" aria-controls="orders" hidden>
<table id="orders">
<thead><tr><th>Customer</th><th>Total</th></tr></thead>
<tbody>
<tr><td>Maya Lin</td><td><data value="1240">$1,240.00</data></td></tr>
<tr><td>Bo Ito</td><td><data value="18">$18.00</data></td></tr>
</tbody>
</table>The filter box carries hidden because it only works with JavaScript; TagAction shows it. Any control that needs TagAction can do the same.
A dropdown that still works without JavaScript (the list simply stays open):
<button aria-expanded="false" aria-controls="account">Account</button>
<ul id="account">
<li><a href="/profile">Profile</a></li>
<li><a href="/logout">Sign out</a></li>
</ul>data-tagaction="off" on any element turns TagAction off for it and everything inside it. On <html> it turns TagAction off for the page. On a <th> it keeps that column from sorting.
A single MutationObserver enhances anything added to the page, including htmx swaps. To enhance content yourself (inside a shadow root, for example), call:
TagAction.init(element);init is safe to call any number of times on the same content.
Current Chrome, Edge, Firefox, and Safari. Where a browser lacks commandfor, exclusive <details name>, or CSS field-sizing, TagAction fills the gap.
TagAction 0.1.0 is tested with TagBrush.css 1.1.0.
npm install
npm run build # src/ → tagaction.js, tagaction.min.js, ai/ instruction files
npm test # Playwright: Chromium, Firefox, WebKitsrc/behaviors/has one module per behavior. Each exports an idempotentinit(root).llms.txtis the source of truth for agent docs;ai/is generated from it. Don't editai/by hand.- The tests check every behavior with mouse, keyboard, and content added later; the pages with JavaScript off; that
llms.txtonly documents what exists; contrast of everything TagAction inserts, in light and dark mode; and the size budget.
Apache-2.0