Write JavaScript like a pro. Javascript Icon

Follow the ultimate JavaScript roadmap.

When to use a Class or Id in HTML

In this blog post we’re going to explore differences between an HTML class and id attribute! From how this affects browser behaviour all the way through to styling tips with CSS.

First we’ll explore the id attribute and how we can use it, as well as when to use it. This answers many questions newcomers have such as “Should I use a class or id in HTML?” and “Should I style the class or id in CSS?”. Let’s find out!

When to use an id

If you’re new to HTML, an id is a unique identity you can give to an HTML element. We can use as many id attributes as we like, however there are some sensible rules:

Anchors and hyperlinking an id

An id creates special behaviour, you’ll find them in this very blog! Each heading (such as h3 we use so that we can include the id value as part of a URL, which will automatically scroll the user to that part of the web page upon loading.

Imagine a blog post which includes a title “All About JavaScript Closures”, the generated blog heading could look like so:

<h2 id="all-about-javascript-closures">
  All About JavaScript Closures
</h2>

Our URL could then automatically link to that part of the document via the URL:

someblog.com/javascript-closures#all-about-javascript-closures

Styling ids

You can style an id via a CSS selector, interestingly enough we use the same syntax as in the URL with a #:

#all-about-javascript-closures {
  background: red;
}

Just because you can, doesn’t mean you should. I’d recommend avoiding styling the id as it’s considered unique. Unless there’s a specific hack you’re planning on making, I’d avoid styling your IDs as you’re only limiting your CSS reuse and subsequently bloating the stylesheet.

Angular Directives In-Depth eBook Cover

Free eBook

Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon Setters and Getters for Styles and Class Bindings

Selecting an id with JavaScript

Interestingly enough, any id properties become JavaScript properties on the global window object.

So if we did this, we would in fact create a global variable with the same name:

<aside id="author">...</aside>

<script>
window.author; // <aside id="author"></aside>
</script>

But global variables aren’t great or reliable, so really we should avoid them when architecting our HTML.

It’s most likely that with your JavaScript you’re better off selecting and changing a class - but should you need it, you know the id is there.

Now there is also a classList API which was created directly for working with your class attribute, so there is no need to use an id in reality.

When to use a class

A class is our preferred way of identifying elements.

Once we’ve bound a class to an element, it becomes targetable through CSS and JavaScript.

Styling a class

We should use a class for styling purposes and optionally reflecting state onto the DOM tree (i.e. for adding behaviour or simply a static style).

The DOM tree is a live representation of our HTML page and is what we use with JavaScript. For example, document.querySelector is a DOM API and not “JavaScript”.

Classes enable us to specify a description for a shared style, whilst providing some meaning behind the element:

<button class="btn">Small button</button>
<button class="btn">Medium button</button>
<button class="btn">Large button</button>

We could then use .btn { background: blue } in our stylesheet to then provide a single style rule to all of these elements! Unlike an id, we can declare a class as many times as we want - to become as efficient and reusable as we can.

Classes are also composable, and we can specify multiple classes per element, giving us the ability to not only inherit a single shared style but also provide an adaptation, such as small, medium and large as below:

<button class="btn btn--small">Small button</button>
<button class="btn btn--medium">Medium button</button>
<button class="btn btn--large">Large button</button>

It could be that we expect use the BEM Methodology and supply a modifier class, denoted with a --suffix:

.btn--small { font-size: 12px }
.btn--medium { font-size: 14px }
.btn--large { font-size: 16px }

In this case, the --small would describe a modified version from the base of .btn. It’s been my preferred CSS methodology for many years.

🕵️‍♀️ With the switch to component-based architecture with web applications, I favour as few styles as possible in my style.css and would look to supply a style per component. This is a better component architecture pattern as it also provides full encapsulation.

With this in mind, we should also use a class to dynamically change values that relate to styling. For instance, we could have an 'active' class that needs adding or removing based on a certain condition. How do we do that?

Angular Directives In-Depth eBook Cover

Free eBook

Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon Setters and Getters for Styles and Class Bindings

Using the classList API

There happens to be a built-in new-ish API, that will require a polyfill for older browsers, called classList which is available to us on every Element DOM Node.

When we log .classList our on an element, we are returned a DOMTokenList for us to work with.

<button class="btn btn--small">Small button</button>

<script>
const button = document.querySelector('.btn .btn--small');

// ▶ DOMTokenList(2) ["btn", "btn--small", value: "btn btn--small"]
console.log(button.classList);
</script>

You can see classList contains a value property that reflects the current class string value.

It also looks like an array, as  ["btn", "btn--small"] look like array elements. It’s almost an array, but because it’s providing value and other classList behaviours in the prototype - it’s array-like with extra behaviours. If you need to use the values as an array you could use Array.from(button.classList).

The classList feature also ships with some great prototype methods to add/remove/toggle and more with a class:

<button class="btn btn--small">Small button</button>

<script>
const button = document.querySelector('.btn .btn--small');

// add + remove a class
button.classList.add('btn--large');
button.classList.remove('btn--small');

// toggle class on a click event
button.addEventListener('click', () => button.classList.toggle('btn--clicked'));
</script>

There’s also much more in the classList documentation I’d encourage you to check out as well.

Summary

We’ve covered a whole lot of ground in this article! From a simple HTML element id or class through to how it affects our global variables in JavaScript and finally exploring APIs such as classList - and how they fit into the ecosystem.

Summing up, here’s a recap of what we’ve learned:

If you are serious about your HTML and CSS skills, your next step is to take a look at our HTML + CSS Basics course that will teach you the full language basics in detail as well as many use cases you’ll need in daily front-end development!

Thanks for reading!

Learn JavaScript the right way.

The most complete guide to learning JavaScript ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover