Purpose and content model
Id gives an element a unique identifier in its tree. Class assigns reusable tokens used by CSS, JavaScript, and application conventions. Data-* stores custom application data on elements. These attributes do not create visual styling or behavior by themselves; another part of the application must use them.
Choose IDs for stable relationships such as fragment targets and labels. Choose classes for groups of elements sharing a role in the implementation. Choose data attributes for application metadata that belongs with the element, not for private values or essential reader-facing content.
Syntax and working example
<h2 id="opening-hours" class="section-title">Opening hours</h2>
<a href="#opening-hours">Jump to opening hours</a>
<article class="book-card featured" data-book-id="BK-204">Urban gardens</article>
Supported attributes and behavior
An HTML ID must be nonempty, unique in its tree, and contain no ASCII whitespace. Class is a space-separated token list. Data attribute names use the data- prefix; JavaScript dataset maps common hyphenated names to camelCase properties. Dataset values are strings, so a value such as false remains a nonempty string until deliberately interpreted. CSS selectors may require escaping for IDs containing special characters even when the ID itself is valid HTML.
Another practical pattern
<button type="button" data-action="save" data-draft-id="42">Save draft</button>
<script>
const button = document.querySelector("[data-action=save]");
console.log(button.dataset.draftId); // The string "42".
</script>
Accessibility and browser notes
IDs support important accessible relationships such as label for and aria-labelledby. Duplicate IDs can silently attach a label to the wrong control. Data attributes are not announced as visible help or accessible names, so instructions should remain ordinary page content.
Common mistakes
Do not expose secrets in data attributes or trust client-provided IDs as authorization. Avoid depending on elements becoming global window properties from their IDs. Renaming an ID can break incoming fragment links even when the page's appearance remains unchanged.
Verify your implementation
Check uniqueness after rendering repeated components. Test all fragment and label relationships and inspect dataset value types. If a data value reaches the server, validate both its format and whether the current user is allowed to act on the referenced object.
Standard status and sources
Standard; browser availability must be checked independently of specification status.