The id Attribute β Unique Identifier
The id attribute gives an element a unique name on the page. Only one element on a given HTML page should have a particular id value. Think of it as a passport number β unique to that individual element.
<header id="site-header">β¦</header>
<main id="main-content">β¦</main>
<footer id="site-footer">β¦</footer>
Using id in CSS
Target an id with the # selector. ID selectors have high CSS specificity β they override class and element selectors.
#site-header {
position: sticky;
top: 0;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
#main-content {
max-width: 860px;
margin: 0 auto;
padding: 2rem 1rem;
}
Using id in JavaScript
document.getElementById() is the fastest DOM selector β it searches only by id and returns a single element (or null).
const header = document.getElementById('site-header');
header.classList.toggle('scrolled');
// Also works with querySelector (slightly slower, more flexible)
const main = document.querySelector('#main-content');
main.style.opacity = '1';
id for Fragment Links
Any element with an id can be linked to directly within the page β or from an external URL.
<!-- In-page jump link (Table of Contents) -->
<nav>
<a href="#intro">Introduction</a>
<a href="#examples">Examples</a>
<a href="#faq">FAQ</a>
</nav>
<h2 id="intro">Introduction</h2>
<h2 id="examples">Examples</h2>
<h2 id="faq">FAQ</h2>
<!-- Cross-page fragment link -->
<a href="/html/core-elements/tables.html#colspan-rowspan">
Jump to colspan section
</a>
The class Attribute β Reusable Labels
The class attribute assigns one or more reusable style labels to an element. Multiple elements can share the same class, and a single element can have multiple classes separated by spaces.
<!-- Many elements sharing one class -->
<div class="card">Card One</div>
<div class="card">Card Two</div>
<div class="card">Card Three</div>
<!-- Multiple classes on one element -->
<button class="btn btn-primary btn-large">Enrol Now</button>
<button class="btn btn-secondary">Learn More</button>
Using class in CSS
Target a class with the . selector. Class specificity is lower than id but higher than element selectors.
.card {
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 1.25rem;
background: #fff;
}
.btn {
display: inline-block;
padding: 0.5rem 1.25rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
}
.btn-primary { background: #0d6efd; color: #fff; }
.btn-secondary { background: #6c757d; color: #fff; }
.btn-large { font-size: 1.1rem; padding: 0.75rem 2rem; }
Using class in JavaScript
// Select all elements with class "card"
const cards = document.querySelectorAll('.card');
// Toggle a class on/off
document.querySelector('.btn-primary').addEventListener('click', function() {
this.classList.toggle('btn--active');
});
// Add / remove / check classes
const el = document.querySelector('.card');
el.classList.add('card--featured');
el.classList.remove('card--featured');
el.classList.contains('btn-primary'); // true or false
id vs class β Comparison Table
| Property | id |
class |
|---|---|---|
| Uniqueness | Must be unique per page | Can be shared by many elements |
| Multiple per element? | One id per element | Multiple classes per element (space-separated) |
| CSS selector | #id-name | .class-name |
| CSS specificity | High (0,1,0,0) | Medium (0,0,1,0) |
| JS selector | getElementById('name') | querySelectorAll('.name') |
| Fragment links? | Yes β href="#id" | No |
| Best used for | Unique landmarks, JS hooks, page anchors | Reusable styles, component patterns |
Naming Conventions
Good names are descriptive, lowercase, and use hyphens to separate words (kebab-case). Avoid camelCase, underscores, or names that describe appearance rather than purpose.
<!-- β
Good names: descriptive, kebab-case -->
<div class="course-card">β¦</div>
<nav id="main-navigation">β¦</nav>
<button class="enrol-btn">β¦</button>
<section id="about-section">β¦</section>
<!-- β Bad: appearance-based names (brittle when design changes) -->
<div class="blue-box">β¦</div>
<p class="big-text">β¦</p>
<!-- β Bad: camelCase (inconsistent with HTML conventions) -->
<div class="courseCard">β¦</div>
<!-- β Bad: too generic (hard to maintain in large codebases) -->
<div class="box">β¦</div>
<div class="item">β¦</div>
BEM Methodology β Block, Element, Modifier
BEM (Block__Element--Modifier) is a popular CSS class naming convention developed at Yandex. It structures class names to make the relationship between HTML and CSS explicit and predictable.
- Block β a standalone component:
.card,.nav,.btn - Element β a part of the block, separated by
__:.card__title,.card__body - Modifier β a variation or state, separated by
--:.btn--primary,.card--featured
<!-- BEM example: a course card component -->
<div class="course-card course-card--featured">
<img class="course-card__thumbnail" src="html.png" alt="HTML course">
<div class="course-card__body">
<span class="course-card__tag course-card__tag--beginner">Beginner</span>
<h2 class="course-card__title">HTML Fundamentals</h2>
<p class="course-card__description">Learn HTML from scratch.</p>
<a class="btn btn--primary" href="/html/">Start Learning</a>
</div>
</div>
.course-card { border: 1px solid #dee2e6; border-radius: 8px; overflow: hidden; }
.course-card--featured { border-color: #0d6efd; box-shadow: 0 4px 12px rgba(13,110,253,0.2); }
.course-card__thumbnail { width: 100%; height: 160px; object-fit: cover; }
.course-card__body { padding: 1rem; }
.course-card__title { margin: 0.5rem 0; font-size: 1.2rem; }
.course-card__description { color: #6c757d; font-size: 0.9rem; }
.course-card__tag { display: inline-block; padding: 0.2rem 0.6rem; border-radius: 12px; font-size: 0.75rem; }
.course-card__tag--beginner { background: #d1e7dd; color: #0a3622; }
Multiple Classes on One Element
Separating classes by spaces lets you compose styles from small, single-purpose classes β a pattern popularised by utility-first CSS frameworks like Tailwind CSS.
<!-- Base class + variant class + size class -->
<button class="btn btn-primary btn-large">Start Course</button>
<button class="btn btn-outline btn-small">Preview</button>
<!-- State classes added by JavaScript -->
<div class="accordion accordion--open">β¦</div>
<div class="accordion">β¦</div>
<!-- Multiple utility classes (Tailwind-style) -->
<p class="text-lg font-bold text-gray-800 mb-4">
Learn to code for free.
</p>
Using Classes as JavaScript Hooks
A common pattern is to use dedicated classes purely as JavaScript selectors β prefixed with js- to signal they should not be styled or removed by CSS refactors.
<!-- Separate styling class from JS hook class -->
<button class="btn btn-primary js-enrol-btn" data-course="html-101">
Enrol Now
</button>
<input class="search-input js-search-input" type="search" placeholder="Searchβ¦">
// Target the JS hook β not the styling class
document.querySelectorAll('.js-enrol-btn').forEach(btn => {
btn.addEventListener('click', () => {
const course = btn.dataset.course;
enrolUser(course);
});
});
// If CSS changes btn to something else, JS still works
// because .js-enrol-btn was not touched by the CSS refactor
Best Practices
- Use classes for styling β keep id for unique landmarks and JavaScript hooks that require a single-element reference.
- Descriptive over presentational β name classes after what the element is (
lesson-header) not how it looks (blue-box). - Keep class names short but clear β
nav-linkis better thannornavigation-link-element. - Use kebab-case β
course-card, notcourseCardorcourse_card. - Avoid overly specific selectors in CSS β
.card .titleis hard to reuse;.card__title(BEM) is self-contained. - Don't rely solely on ids for CSS β high specificity makes overrides painful. Use classes for most styling.
π Summary
idβ unique per page; CSS#selector; JSgetElementById(); enables fragment links. Use for landmarks and single-element JS hooks.classβ reusable; multiple per element; CSS.selector; JSquerySelectorAll(). Use for all styling and most JS targeting.- Name classes descriptively in kebab-case based on purpose, not appearance.
- BEM (
block__element--modifier) is a scalable naming convention for larger codebases. - Use
js-prefixed classes as pure JavaScript hooks, separate from styling classes. - Multiple classes on one element allow modular, composable styling:
class="btn btn-primary btn-large".
Frequently Asked Questions
What happens if two elements share the same id?
The page will still render, but it is invalid HTML. getElementById() returns only the first matching element. CSS may apply to both (browsers are forgiving), but fragment links will jump to the first match. Validators and accessibility checkers will flag it as an error. Always ensure ids are unique.
Is it bad to use id for CSS styling?
Not inherently bad, but id selectors have much higher specificity than class selectors β they are harder to override without using !important or another id selector. For component-level styles, class selectors are almost always the better choice. Use id for unique page-level elements like #main-navigation where you know there will only ever be one.
Can a class name start with a number?
In HTML the class value can technically start with a number, but in CSS a class selector starting with a digit is invalid and requires escaping (.\31 st-item for class 1st-item). Always start class and id names with a letter or hyphen followed by a letter to avoid this complication.
What is the difference between class and className in JavaScript?
In HTML the attribute is class. In JavaScript the DOM property is className β because class is a reserved keyword in JavaScript. You can read and write it as a string: el.className = 'btn btn-primary'. The modern and preferred approach is to use el.classList which provides add(), remove(), toggle(), and contains() methods for manipulating individual classes without overwriting the entire string.