html-class-modifier
v0.1.0
Published
A script that enables developers to dynamically modify the class attribute of target elements by adding a single data attribute to the trigger element. Toggling, adding, and removing classes — on one or many targets, in any order, optionally staggered ove
Maintainers
Readme
HTML Class Modifier
A script that enables developers to dynamically modify the class attribute of target elements by adding a single data attribute to the trigger element. Toggling, adding, and removing classes — on one or many targets, in any order, optionally staggered over time — are all expressed as steps in one JSON list:
- A single step
- Multiple steps on the same target
- Multiple steps on different targets
- Delaying steps
- A staggered reveal
Installation
Option 1: npm
npm install html-class-modifierimport { HTML_Class_Modifier } from 'html-class-modifier';
new HTML_Class_Modifier();Option 2: Script tag
No build step needed. Include the minified script directly and it initializes itself as window.hcm:
<script src="https://cdn.jsdelivr.net/npm/html-class-modifier/dist/html-class-modifier.min.js"></script>Both options expose the same data-attribute API described below.
Usage
The data-modify Attribute
Add data-modify to a trigger element. Its value is JSON: either a single step object, or an array of steps for that element to run in order when clicked.
{ "target": "<CSS selector>", "class": "<class name>", "action": "toggle" | "add" | "remove", "delay"?: <milliseconds> }target— any valid CSS selector, including comma-separated lists (e.g."#element-1, #element-2") — passed directly toquerySelectorAll.class— the single class name this step applies. Need to change more than one class? Add more steps.action—"toggle","add", or"remove".delay(optional) — milliseconds to wait after the previous step ran before running this one (default0). Steps form a chained timeline: with delays0, 400, 400, the three steps fire att=0,t=400,t=800.
A step missing target, class, or a valid action is skipped (logged to the console) without affecting the rest of the sequence or its timing.
Why chained instead of "delay from click"? Chaining is what most real use cases need for free: a staggered reveal across several elements is just
delay: 0, 100, 100, ...with no arithmetic, and steps that should fire at the exact same moment can simply sit next to each other withdelay: 0between them. There's no separate timeline mode to choose — one model, no extra concept to learn.
Examples
A single step
Toggle the class "show" on "#element"
<div id="element" class="show">Element</div>
<button data-modify='{"target": "#element", "class": "show", "action": "toggle"}' type="button">Trigger Element</button>Multiple steps on the same target
Toggle "show" and add "active" on "#element"
<div id="element" class="show">Element</div>
<button data-modify='[
{ "target": "#element", "class": "show", "action": "toggle" },
{ "target": "#element", "class": "active", "action": "add" }
]' type="button">Trigger Element</button>Multiple steps on different targets
Remove "show" from "#element-1", add "active" to "#element-2", and toggle "highlight" on every ".element-3"
<div id="element-1" class="show">Element 1</div>
<div id="element-2">Element 2</div>
<div class="element-3">Element 3-1</div>
<div class="element-3">Element 3-2</div>
<button data-modify='[
{ "target": "#element-1", "class": "show", "action": "remove" },
{ "target": "#element-2", "class": "active", "action": "add" },
{ "target": ".element-3", "class": "highlight", "action": "toggle" }
]' type="button">Trigger Element</button>Delaying steps
Show "#element" immediately, then add "active" 400ms later (e.g. to let a CSS transition on display/opacity settle before triggering another one)
<div id="element" class="hidden">Element</div>
<button data-modify='[
{ "target": "#element", "class": "hidden", "action": "remove" },
{ "target": "#element", "class": "active", "action": "add", "delay": 400 }
]' type="button">Trigger Element</button>A staggered reveal
Reveal three list items one after another, 100ms apart, with no manual timing math — each step's delay only needs to account for the gap since the previous one
<ul>
<li id="item-1" class="hidden">Item 1</li>
<li id="item-2" class="hidden">Item 2</li>
<li id="item-3" class="hidden">Item 3</li>
</ul>
<button data-modify='[
{ "target": "#item-1", "class": "hidden", "action": "remove" },
{ "target": "#item-2", "class": "hidden", "action": "remove", "delay": 100 },
{ "target": "#item-3", "class": "hidden", "action": "remove", "delay": 100 }
]' type="button">Trigger Element</button>