9

I'm learning about jQuery selector.

w3schools tutorial says that "Do not start an id attribute with a number. It may cause problems in some browsers". I tested and saw it really does not work. I wonder what the technical reason of this issue is?

Nope
  • 22,147
  • 7
  • 47
  • 72
ibrahim
  • 3,254
  • 7
  • 42
  • 56
  • 5
    I would rather say *Do not start* learning about web development from W3Schools – Mr. Alien Mar 03 '14 at 07:53
  • Have a look at [**w3fools**](http://w3fools.com) in regards to w3schools. On topic though, this is not a jQuery rule but a rule driven by CSS/HTML standards. If you are looking for information on anything with CSS or JavaScript there is plenty of resources out there != w3schools. The [**CSS MDN**](https://developer.mozilla.org/en-US/docs/Web/CSS) is a good start and they got docs for JavaScript, HTML, etc.. and the actual [**W3**](http://www.w3.org/standards/webdesign/script) docs but they can be hard to read at times. – Nope Mar 03 '14 at 08:00

2 Answers2

9

Why can an element id not start with an integer?

They can. But a CSS ID selector cannot start with a digit. E.g., this HTML is valid:

<div id="1foo">testing 1 2 3</div>

...but this CSS is not valid:

#1foo {
    color: green;
}

The CSS standard says that an id selector cannot start with an unescaped digit:

An ID selector contains a "number sign" (U+0023, #) immediately followed by the ID value, which must be an CSS identifiers.

And then defining CSS identifier:

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F".

(My emphasis.)

So in theory, you can work around the #1foo not working by escaping the digit in the CSS selector. For instance:

HTML:

<div id="1foo">testing 1 2 3</div>

CSS:

#\31 foo {
    color: green;
}

...where 31 is the character code for "1" in hex. Live Example:

#\31 foo {
  color: green;
}
<div id="1foo">testing 1 2 3</div>

But the selector can't literally start with a digit, and in general it's such a hassle I would avoid bothering. I also can't speak to how well the various things that need to interpret CSS selectors work when doing this. jQuery handles it correctly, FWIW. E.g.:

$("#\\31 foo").css("color", "blue");

...works. Live Example:

setTimeout(function() {
  $("#\\31 foo").css("color", "blue");
}, 2000);
#\31 foo {
  color: green;
}
<div id="1foo">testing 1 2 3, this should be green, and in two seconds it'll turn blue</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

(Note that you have to escape the backslash in the string, because backslashes are special in JavaScript strings, so to get an actual backslash in the selector, you need two in the string.)

As for why CSS would have this restriction (and why HTML used to, although browsers never enforced it), we can only speculate. Mr. Alien points out in the comments that most programming languages disallow starting identifiers with a digit. HTML and CSS are not, of course, programming languages, but the id values created via HTML are reflected as property names in DOM objects, which are accessed via programming languages. It may just be that the people doing the specs were following what they felt was convention or trying to provide some compatibility with programming languages. That's speculation, though.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Not just CSS, it's a standard.. – Mr. Alien Mar 03 '14 at 07:53
  • 1
    I pointed JavaScript, so I used the word Standard.. Also, there was no CSS included in the question.. So I pushed that comment :) that's its a standard rule amongst many languages – Mr. Alien Mar 03 '14 at 07:57
  • 1
    @T.J.Crowder It's my understanding that CSS (at least since 2) *can* handle either an ID or a class name that starts with a number, *provided* that the numbers are escaped. (That is, it's a restriction of the rule parsing rules, not an underlying business rule.) – user2864740 Mar 03 '14 at 08:00
  • 1
    @user2864740 Yea, just like [this](http://stackoverflow.com/a/22141492/1542290) – Mr. Alien Mar 03 '14 at 08:01
  • Except for HTML5 where numeric ID's are perfectly fine – Eric Herlitz Mar 03 '14 at 08:05
  • @user2864740: Indeed, you're right, I've updated to demonstrate that. – T.J. Crowder Mar 03 '14 at 08:06
  • This is really a limitation of CSS. HTML 5 has very relaxed requirements on the `id` attribute: *There are no other restrictions on what form an ID can take; in particular, IDs can consist of just digits, start with a digit, start with an underscore, consist of just punctuation, etc.* https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute – connexo Apr 12 '21 at 11:27
  • @connexo - Right. I said in my first sentence that they're valid HTML, and linked to the then-specification for it. – T.J. Crowder Apr 12 '21 at 11:37
2

Actually, you can make an id start with a number, and methods like document.getElementById works just fine with that.

But some older page use the legacy IE standard that an element like

<div id="hello">World</div>

can be referenced as document.hello. Of course this syntax doesn't work, but I think document["123id"] can fix it.

But, above all, CSS selectors don't work well with id's starting with a number. You have to escape them:

#123id {color: red;}      /* It doesn't work */

#\31 23id {color: blue;}  /* Oh yeah! */

Worth the effort? Probably not.

MaxArt
  • 22,200
  • 10
  • 82
  • 81