HTML Attributes Table
| Attribute | Applies to | What it does |
|---|---|---|
id | All elements | Unique identifier - CSS #id, JS getElementById, anchor targets |
class | All elements | Space-separated category list - the CSS workhorse |
style | All elements | Inline CSS - last-resort styling; prefer stylesheets |
title | All elements | Native tooltip on hover; also the accessible name for iframes |
hidden | All elements | Boolean: removes the element from display and a11y tree |
tabindex | Interactive elements | 0 = natural order, positive = manual order (avoid), -1 = programmatic focus only |
lang | All elements | BCP-47 language tag - drives screen-reader pronunciation and hyphenation |
dir | All elements | ltr, rtl or auto - text direction for multilingual content |
data-* | All elements | Custom data shelf readable via dataset - the sanctioned JS hook |
aria-* | All elements | Accessibility semantics - roles, states, live regions |
contenteditable | Any element | Boolean: turns the region into an editable surface |
spellcheck | Editable text | Boolean: browser spell-check on/off |
draggable | All elements | Boolean: enables the HTML5 drag-and-drop source side |
autocapitalize / inputmode | Text inputs | Mobile keyboard hints - inputmode="numeric" beats type hacks |
id once per element for scripting hooks, class for styling, and data-* for everything custom - never invent attributes; unknown ones break validation and confuse parsers. Related tools: semantic elements table, HTML entities table, escape html, and web vitals table for the performance side of the markup you write.HTML attributes are the settings panel of every element, and thirteen of them are global - legal on any tag, from a div to a button. The table below lists the working set with an honest note per attribute: what it actually does, and where its misuse shows up later.
Bottom line: id is a unique scripting and fragment anchor - one per page, no recycling. class is the styling workhorse - many per element, reusable freely. Everything custom goes in data-* attributes, which exist precisely so you never invent attribute names that break validation and confuse every parser downstream.
The honest part: two attributes on this table do quiet heavy lifting that most tutorials skip. lang enables correct screen-reader pronunciation and hyphenation - an accessibility lever disguised as metadata. And inputmode on mobile forms changes the keyboard itself, which fixes more number-entry complaints than any validation message ever will.
How to use
- Find the attribute in the table; the Applies-to column tells you whether it is truly global or form-specific.
- Read the third column for the rule that prevents the common mistake - tabindex ordering, hidden vs CSS display, boolean-attribute syntax.
- Pair this with the semantic elements table: the element chooses the meaning, the attributes carry the behavior.
Frequently asked questions
What is the difference between id and class?
id is unique - one element per page, used for fragment links (#section), label association, and getElementById. class is a category tag - many per element, shared across unlimited elements, and the primary CSS selector. The classic mistake is styling by id: it works until you need the same style twice, and specificity fights begin. Style with classes, target with ids.
How does the tabindex attribute actually work?
Three values, three behaviors: 0 puts an element into the natural keyboard order (the fix for making a div focusable); -1 allows programmatic focus only (skip the Tab key - useful for modal dialogs); any positive number hijacks the tab order into a manual sequence that you must now maintain forever. Positive values are almost always a bug in disguise - the real fix is DOM order that matches visual order.
What are data-* attributes for?
They are the sanctioned place to attach your own data to an element: data-user-id="42" becomes element.dataset.userId in JavaScript. Browsers never act on them, validation passes, and CSS can even select them ([data-state="open"]). The alternative - inventing attributes like userid="42" - breaks HTML validation, confuses tools, and collides with future standards. Anything the DOM needs to remember that has no built-in attribute belongs in data-*.
Do hidden and CSS display:none do the same thing?
Almost - and the difference is semantic honesty. The hidden attribute means this content is not relevant now: it removes the element from rendering AND from the accessibility tree, regardless of stylesheets. A CSS class that sets display:none can be overridden by any more specific style, leaving content technically invisible but still announced to screen readers. Use hidden for state (a panel not currently shown), CSS for presentation.