Skip to main content Skip to navigation
All Posts All Tags

Improve the format of your JavaScript selectors

This outlines my recommended approach for selecting elements in JavaScript.

There are loads of ways to select elements with JavaScript...

  • querySelector()
  • querySelectorAll()
  • getElementByID()
  • getElementsByClassName()
  • getElementsByName()
  • getElementsByTagName()
  • getElementsByTagNameNS()

There's probably even more than that!

Inside those methods you pass in parameters to select the element(s) you want (check the docs for each method if you want to know what params they can take).

Personally, I like to use querySelector() and querySelectorAll pretty much exclusively. Their params are just like CSS selectors we all know and love.

// selector examples:
const myElement = document.querySelector('.class-name');
const myElement2 = document.querySelector('#unique-ID');
const myElement3 = document.querySelector('[name="rating"]');
const myNodeList = document.querySelectorAll('button');
// get the idea!
A quick note about querySelector()

Remember, you don't always have to use document with querySelector().

An alternative can be to query other elements you've already selected, making DOM traversal faster.

const form = document.querySelector('.js-form');
const toggleButton = form.querySelector('.js-toggle');

This slightly improves performance when you can use it.

Do you see how messy and inconsistent it can become, using whatever old JS selector you like? That inconsistency becomes even more evident once you work with others in a team.

⚠️ It's really good to have code standards for these things!

If you start implementing selectors consistently now, I promise your future self (and any devs who have to work on your code in future) will thank you for it!

The problem

Inconsistency, mixed selectors, and (even worse) nested element selectors are the enemy of clean code.

The biggest issue of all when you use (or a team uses) inconsistent approaches to element selection is it makes your code vulnerable to bugs being caused by code in other files. You lose all visibility in HTML of what JavaScript is doing.

Another issue with inconsistent selectors is it simply slows a team down. You have to think afresh every time, "what shall I use to get my element here?" Exhausting.

The solution

Use a consistent method of element selection that's reserved only for JavaScript.

1. Prefixed classes

💡 I recommend using js- prefixed class selectors on every element you need to select in JavaScript, along with querySelector() or querySelectorAll, like this:

<button class="js-toggle">...
/* JS */
const toggleButton = document.querySelector('.js-toggle');

This approach removes all ambiguity. It can be consistently applied across a team and is immediately clear when looking at the HTML what is being affected by JavaScript. That is a huge bonus!

2. Custom data attribute

A very similar alternative that's just as good is using a specific data attribute for every element you want to select with JavaScript, like this:

<button data-js="toggle">...
/* JS */
const toggleButton = document.querySelector('[data-js="toggle"]');

Try one of these approaches out and see how you get on...


  • Using a specific and consistent method for JS selectors
    • removes ambiguity
    • bakes in that consistency
    • removes some cognitive burden on developers
    • and provides clear visibility of what JavaScript is doing in the HTML, leading to fewer unexpected bugs.
  • Establishing code standards — such as "This is how we always select elements in JavaScript" — can only improve your code and your team's efficiency.

It's never too early to start building good habits! 😉