HTML id and class Attributes
Almost every HTML element can carry two special attributes: id and class. They don’t change how an element looks or behaves on their own — instead, they act as labels that let CSS, JavaScript, and even other HTML elements (through links) target specific parts of a page. Understanding the difference between them, and the rules that govern each, is foundational to writing maintainable HTML.
Overview / How it works
The id attribute gives a single element a unique identifier within the entire HTML document. Think of it like a Social Security number for an element — no two elements on the same page should ever share the same id value. Because it’s unique, an id is perfect for pinpointing exactly one element: jumping to it with a page anchor, labeling it for an associated form control, or selecting it with a highly specific CSS rule.
The class attribute is the opposite in spirit: it’s a label meant to be shared. Many elements can carry the same class name, and a single element can carry several class names at once, separated by spaces. Classes exist to group elements that share a role or style, such as every warning message on a page, or every card in a product grid.
Neither attribute affects rendering by itself. The browser parses them as plain strings and stores them in the DOM as node properties (element.id and element.classList/element.className). They only produce a visible effect once something else — a CSS selector, a JavaScript query, or a URL fragment — references them. In other words, id and class are hooks, not styles. Styling itself belongs to CSS, and behavior belongs to JavaScript; this HTML lesson only covers how to correctly attach the hooks.
Both attributes are part of the HTML “global attributes” set, meaning they can be applied to virtually any HTML element, from <div> and <p> to <table> and <svg>.
Syntax
<tagname id="unique-name" class="group-name another-group">content</tagname>
- id — a single token (no spaces). Must be unique across the whole document. Case-sensitive.
- class — one or more tokens separated by single spaces. Not required to be unique; the same class can appear on any number of elements, and one element can list several classes.
| Rule | id | class |
|---|---|---|
| Uniqueness | Must be unique in the document | Can repeat freely |
| Multiple values allowed? | No — one value only | Yes — space-separated list |
| Typical use | Anchor links, form labels, one-off JS/CSS targeting | Shared styling, grouping, bulk JS/CSS targeting |
| CSS selector | #name |
.name |
Valid characters
Modern HTML allows almost any character in an id or class name except whitespace, but for compatibility and readability it’s best practice to stick to letters, digits, hyphens, and underscores, and to start the value with a letter. Avoid spaces, punctuation like # or ., and starting with a digit, since those cause problems in CSS selectors and older tooling.
Examples
Example 1: A unique id for page navigation
<h2 id="contact">Contact Us</h2>
<p>Reach out any time at hello@example.com.</p>
<a href="#contact">Jump to Contact section</a>
Result: The page renders a heading, a paragraph, and a link reading “Jump to Contact section”. Clicking the link scrolls the browser viewport so the <h2> with id="contact" is brought into view, because the href value #contact matches that element’s id.
This is one of the most common real-world uses of id: creating an in-page anchor that a link (or an external URL with a #fragment) can jump straight to.
Example 2: Shared classes for consistent grouping
<ul>
<li class="fruit">Apple</li>
<li class="fruit">Banana</li>
<li class="vegetable">Carrot</li>
</ul>
Result: A bulleted list with three items — Apple, Banana, Carrot. Nothing looks different yet, because no CSS rule references .fruit or .vegetable. But in the DOM, the first two <li> elements now share the class fruit, so a single CSS rule like .fruit { } or a single JavaScript call like document.querySelectorAll('.fruit') could style or select both at once, without touching Carrot.
This demonstrates the grouping power of class: one label, applied to many elements, lets you treat them as a set.
Example 3: Combining id and multiple classes on one element
<article id="post-42" class="post featured highlighted">
<h2>Why Semantic HTML Matters</h2>
<p>Semantic elements describe meaning, not just appearance.</p>
</article>
Result: An article block renders with its heading and paragraph. The element carries a unique id (post-42) for direct linking or JavaScript lookup, plus three separate classes (post, featured, highlighted) space-separated in one attribute. Each class can be targeted independently in CSS — .post might style every article uniformly, while .featured adds an extra visual treatment only to some.
This shows that id and class are not mutually exclusive — most real elements use both: one unique id for identity, and a set of classes for shared styling roles.
How it works step by step
- The browser’s HTML parser reads the opening tag and builds a DOM element node.
- Any
idattribute value is stored on that node and registered so it can be found instantly viadocument.getElementById()or a#idCSS selector — internally, browsers keep a fast lookup map from id strings to elements. - Any
classattribute value is split on whitespace into a list, exposed aselement.classList, and each token is indexed so.classCSS selectors andgetElementsByClassName()can match quickly across many elements. - When the CSS engine computes styles, it matches selectors like
#contactor.fruitagainst these stored values to decide which rules apply to which elements. - If two elements share the same
id, the parser does not throw an error — the page still renders — but behavior becomes unreliable:getElementByIdand#idselectors are only specified to return the first matching element, so the second one becomes unreachable by that id.
Common Mistakes
Mistake 1: Reusing the same id on multiple elements
<div id="card">First card</div>
<div id="card">Second card</div>
This is invalid HTML because id values must be unique per document. The page will still render, but any CSS or JavaScript targeting #card will only reliably reach the first element, silently breaking the second.
<div id="card-1">First card</div>
<div id="card-2">Second card</div>
Fixed: each element gets its own unique id, and a shared class="card" could still be added to both if they need common styling.
Mistake 2: Using spaces or a leading digit inside an id
<section id="2026 events">...</section>
A space inside an id is not allowed since id must be a single token, and starting with a digit causes problems for CSS selectors (a bare #2026 selector is invalid CSS). This snippet is flagged only for illustration and is not meant to be copied.
<section id="events-2026">...</section>
Fixed: hyphenate instead of using spaces, and start with a letter.
Mistake 3: Confusing class with id in a selector
A frequent beginner error is writing class="main" in the HTML but then trying to target it with the id-selector #main in CSS (or vice versa). Since the browser stores class and id separately, the selector simply matches nothing and the intended styling never applies. Always double check that # is used for ids and . is used for classes.
Best Practices
- Use
idonly when you truly need to reference one specific element — page anchors, associating a<label>with a form control viafor/id, or a single unique JavaScript hook. - Use
classfor anything that describes a repeatable role or style, even if only one element currently uses it — it keeps the door open for reuse. - Prefer lowercase, hyphen-separated names (
nav-bar, notNavBarornav_bar) for consistency across HTML and CSS. - Never duplicate an
idvalue anywhere in the same document, including inside embedded SVG or components. - Name ids and classes after what the element is or does (
id="main-nav"), not how it currently looks (id="red-box"), so the markup stays meaningful if the design changes. - Combine multiple classes to compose styles (
class="btn btn-primary") rather than inventing one long combined class name. - Remember that
idvalues are also usable as URL fragments (page.html#section), so choose descriptive, stable id names for sections you expect people to link to directly.
Practice Exercises
- Create an HTML page with three
<h2>section headings, each with a uniqueid. Then add three links at the top of the page that jump to each section using#idhref values. - Write a list of five
<li>items representing tasks. Give the completed tasks a class ofdoneand the pending tasks a class ofpending. (No styling required — just correct attribute usage.) - Take a single
<div>representing a notification banner. Give it a uniqueidfor JavaScript control, plus two classes: one describing that it’s a “banner” and one describing its severity, such as “warning”.
Summary
iduniquely identifies exactly one element per document;classgroups any number of elements together.- An element can have at most one
idbut any number of space-separated classes. idvalues enable page anchors (#idlinks), form label association, and precise single-element targeting.classvalues enable shared styling and bulk selection without duplicating rules.- Neither attribute changes appearance by itself — actual styling comes from CSS, and behavior from JavaScript, both of which use
id/classas selectors. - Duplicate ids are invalid and cause unreliable behavior, even though the browser won’t stop the page from rendering.
