Identifying numbers
Fun learning about CSS today.
Since HTML5, element IDs can start with numbers. But in the CSS selectors spec, and therefore in document.querySelector
, identifiers can’t. So how do you target an element with a numeric ID?
<div id="123">Hello</div>
<style>
#123 { color: red } /* No */
</style>
CSS has a single method of escaping characters for identifiers, and it’s not one of the common ones: you can replace a character with a \ followed by the unicode codepoint for that character in hexadecimal.
#\123 { color: red } /* No */
#"123" { color: red } /* No */
The Unicode codepoints for the digit characters run from 0x30 to 0x39, which means the escape sequence for a leading 1
is \31
.
But if you try escaping this way, you’ll find you still aren’t all of the way there yet.
#\3123 { color: red } /* No */
This is because CSS thinks you’re escaping the codepoint 3123 here (“ㄣ”). Instead, you have to either a) pad the Unicode codepoint to 6 hexadecimal characters, or b) add a space after the escape sequence to finish the escape:
#\00003123 { color: green } /* YES */
#\31 23 { color: green } /* YES */
That’s right, if you want to target id=”123” in CSS (or in Javascript’s querySelector) you end up with this ABOMINATION(!) At that point, if you need this (because you’re generating IDs) you should just add a prefix.
<div id="123">Hello, world!</div>
<style>
#\31 23 { color: green }
</style>
Javascript’s CSSOM library (in browsers by default) has a CSS.escape method which deals with this:
CSS.escape('123') // => "\31 23"
But actually trying to use this in practice makes your Javascript feel as clunky as your CSS is.