Attributes

Course 2 · Ch 7
Data Attributes & Custom Attributes
A standards-compliant way to attach your own data to an HTML element, for CSS and JavaScript to read

Sometimes an element genuinely needs to carry information that has no existing HTML attribute to hold it — a product ID, a sort key, a state flag. data-* attributes are the official, validator-approved way to do exactly this, without inventing non-standard attributes that would fail validation (Fundamentals Chapter 10).

The data-* Syntax

<li data-product-id="4821" data-category="electronics"> Wireless Keyboard </li>

Any attribute name starting with data- is reserved specifically for this purpose and guaranteed never to clash with a current or future standard HTML attribute — exactly why the prefix exists, rather than just inventing arbitrary attribute names directly.

Reading data-* Attributes in JavaScript

// HTML <li data-product-id="4821">Wireless Keyboard</li> // JavaScript — the dataset API converts data-product-id automatically const item = document.querySelector('li'); console.log(item.dataset.productId); // "4821"

Note the naming conversion: a hyphenated attribute name (data-product-id) becomes camelCase in JavaScript's dataset object (productId) — this conversion happens automatically and consistently, the same convention used across the DOM API generally.

Reading data-* Attributes in CSS

// HTML <div data-status="urgent">Task item</div> // CSS — attribute selector, no JavaScript needed at all [data-status="urgent"] { border-left: 4px solid red; }

CSS can select and style elements based on a data attribute's value directly, using a standard attribute selector — genuinely useful for visually distinguishing states (urgent/normal/done, active/inactive) without any scripting at all.

Common Real-World Uses

🏷️ Storing an ID for JS to use later
A list item carrying a database record's ID, read when the user clicks it — avoiding needing a separate lookup table mapping DOM elements to IDs.
🎯 Sort/filter keys
A data-price or data-date attribute holding a raw sortable value, separate from the formatted, human-readable text actually displayed.
🔄 State flags
data-expanded="true" on a collapsible section — readable by both CSS (styling) and JS (behaviour) from the same single source of truth.
🧪 Test hooks
data-testid="submit-button" — a stable identifier for automated testing tools, deliberately decoupled from CSS classes that might change for styling reasons.

Sort Key Example — Separating Display Text from Sortable Value

<ul> <li data-price="9.99">£9.99</li> <li data-price="149.00">£149.00</li> </ul>

Sorting by the displayed text "£9.99" vs "£149.00" alphabetically would put £149.00 first — wrong. Sorting by the raw numeric data-price value instead gives the genuinely correct order. This pattern — display text for humans, a clean machine-readable value in a data attribute — comes up constantly in real interfaces.

data-* attributes are visible in the page source — never store secrets in them
Exactly the same principle as HTML comments (Fundamentals Chapter 10): anything in a data attribute is plainly visible to anyone viewing the page source. Fine for a product ID or a sort key; never appropriate for anything sensitive.

Why Not Just Invent Your Own Attribute Name?

Writing <li productid="4821"> directly (without the data- prefix) works in most browsers today, but is technically invalid HTML — and risks a genuine future collision if HTML's specification ever adds a real, standard attribute with that exact name. The data-* prefix is reserved specifically so this can never happen — a small habit that costs nothing and avoids a real, if rare, category of future bug.

Chapter 7 Quick Reference

  • data-* — the only standards-compliant way to attach custom data to an HTML element
  • JavaScript: element.dataset.propertyName — hyphenated attribute names convert to camelCase automatically
  • CSS: [data-attribute="value"] — a standard attribute selector, no JavaScript needed
  • Common uses: storing IDs for later JS use, sort/filter keys, state flags, stable test hooks (data-testid)
  • Sort key pattern: keep a clean numeric value in a data attribute, separate from formatted display text
  • Never store secrets in data attributes — visible in page source like any other attribute
  • Always use the data- prefix rather than inventing arbitrary attribute names — avoids future spec collisions, keeps the page valid
  • Next chapter: HTML APIs overview — template element, details/summary, dialog element