How to escape CSS selectors in JavaScript
- Published at
- Updated at
- Reading time
- 2min
Here's a trick question: how would you select the following HTML element in JavaScript?
<div id="#">Select me!</div>
Oddly, this element's id is a #
. But as far as I can tell, even though it's uncommon it's still a perfectly valid HTML attribute. So, how would you query this element?
You surely could use the good old document
...
console.log(document.getElementById('#')); // <div id="#">...
This works, but I rarely use getElementById
because it limits me to select elements via an id. Duh! ๐
document
, on the other hand, is more flexible and allows any DOM element to be queried with a CSS selector.
But can you select this "hash id element" with a CSS selector using querySelector
? Turns out you can't.
console.log(document.querySelector('##'));
// SyntaxError: Document.querySelector: '##' is not a valid selector
Unfortunately, ##
isn't a valid CSS selector, and I hear you say, "Come on Stefan, espace the second #
and you're good to go!" and that's right, escaping the #
character works.
console.log(document.querySelector('#\\#')); // <div id="#">...
But do you know all the characters that need to be escaped when you want to query a DOM element? Plenty of valid HTML attribute strings will throw an exception when used to query a DOM element.
document.querySelector('.a:b'); // throws because of the `:`
document.querySelector('[href=@]'); // throws because of the `@`
document.querySelector('.[jooo]'); // throws because of the `[]`
Manually escaping characters isn't a bulletproof solution, but today I learned there's a handy static method in the CSS
JavaScript namespace to help with this exact problem โ CSS
.
escape()
allows you to safely use whatever attribute values your HTML includes.
console.log(`.${CSS.escape('a:b')}`); // ".a\:b"
console.log(`[href=${CSS.escape('@')}]`); // "[href=\@]"
console.log(`.${CSS.escape('[jooo]')}`); // ".\[jooo\]"
Good to know!
You might wonder how often you have to deal with these unusual attribute values. For example, the useId
React hook returns ids that are invalid as CSS selectors. That's one case already, and I bet there are plenty more!
Join 5.4k readers and learn something new every week with Web Weekly.