Why Can't I Have a Numeric Value as the Id of an Element

Why can't I have a numeric value as the ID of an element?

That's just what the spec says.

From the HTML 4 specification:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"),
underscores ("_"), colons (":"), and periods (".").

The good news is that the HTML 5 specification is more lenient:

The id attribute specifies its element's unique identifier (ID).
The value must be unique amongst all the IDs in the element's home
subtree and must contain at least one character. The value must not
contain any space characters.

Why can an element id not start with an integer?

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>

HTML ID with numerical value not recognized by CSS

Although it's allowed to set a class or id to begin with a digit in HTML5, but it's not allowed in CSS, see the spec:

HTML5: 3.2.5.1 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. ...


CSS: 4.1.3 Characters and case

... 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 ...

i.e.

<div id="1"> is valid HTML, but you cannot target it with #1 {...} in CSS.

However, you can use [id="1"] {...} or escape it #\31 {...}

what if element's ID begin with a number

The standard specifies that IDs must start with a letter. If browsers (or rather JavaScript engines) choose to ignore that requirement, then that's just the way it is. Browsers are really forgiving that way ...

What are valid values for the id attribute in HTML?

For HTML 4, the answer is technically:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

HTML 5 is even more permissive, saying only that an id must contain at least one character and may not contain any space characters.

The id attribute is case sensitive in XHTML.

As a purely practical matter, you may want to avoid certain characters. Periods, colons and '#' have special meaning in CSS selectors, so you will have to escape those characters using a backslash in CSS or a double backslash in a selector string passed to jQuery. Think about how often you will have to escape a character in your stylesheets or code before you go crazy with periods and colons in ids.

For example, the HTML declaration <div id="first.name"></div> is valid. You can select that element in CSS as #first\.name and in jQuery like so: $('#first\\.name'). But if you forget the backslash, $('#first.name'), you will have a perfectly valid selector looking for an element with id first and also having class name. This is a bug that is easy to overlook. You might be happier in the long run choosing the id first-name (a hyphen rather than a period), instead.

You can simplify your development tasks by strictly sticking to a naming convention. For example, if you limit yourself entirely to lower-case characters and always separate words with either hyphens or underscores (but not both, pick one and never use the other), then you have an easy-to-remember pattern. You will never wonder "was it firstName or FirstName?" because you will always know that you should type first_name. Prefer camel case? Then limit yourself to that, no hyphens or underscores, and always, consistently use either upper-case or lower-case for the first character, don't mix them.


A now very obscure problem was that at least one browser, Netscape 6, incorrectly treated id attribute values as case-sensitive. That meant that if you had typed id="firstName" in your HTML (lower-case 'f') and #FirstName { color: red } in your CSS (upper-case 'F'), that buggy browser would have failed to set the element's color to red. At the time of this edit, April 2015, I hope you aren't being asked to support Netscape 6. Consider this a historical footnote.

How to select an element that has an ID which begins with a digit?

You can access it by using an attribute selector and selecting the ID attribute: