javascripthtmldomsgml

Is 111 a valid HTML id attribute or are document.querySelector() and document.querySelectorAll() correctly throwing syntax errors?


Given

const  div = document.createElement("div");

div.id = 111;

document.body.appendChild(div);

try {
  console.log(document.querySelector("#111"));
} catch(e) {
  console.error(e); 

  /* 
     Chromium:

     DOMException: Failed to execute 'querySelector' on 'Document':
     '#111' is not a valid selector.

     Firefox
     SyntaxError: '#111' is not a valid selector

  */
}

try {
  console.log(document.querySelectorAll("#111"));
} catch(e) {
  console.error(e); 

  /* 
     Chromium:

     DOMException: Failed to execute 'querySelector' on 'Document':
     '#111' is not a valid selector.

     Firefox
     SyntaxError: '#111' is not a valid selector

  */
}

however, document.getElementById() returns the element

const  div = document.createElement("div");

div.id = 111;

document.body.appendChild(div);

try {
  console.log(document.getElementById("111"));
} catch(e) {
  console.error(e); 
}

References:

6.2 SGML basic types

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 (".").

7.5.2 Element identifiers: the id and class attributes

Attribute definitions

id = name [CS] This attribute assigns a name to an element. This name must be unique in a document.

DOM - Living Standard

While this specification defines requirements for class, id, and slot attributes on any element, it makes no claims as to whether using them is conforming or not.

HTML - Living Standard

The id attribute specifies its element's unique identifier (ID).

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.

Document.querySelector()

Throws a SYNTAX_ERR exception if the specified group of selectors is invalid.

Document.querySelectorAll()

Throws a SYNTAX_ERR exception if the specified group of selectors is invalid.


Is "111" a valid HTML id attribute or are document.querySelector() and document.querySelectorAll() correctly throwing syntax errors?


Solution

  • According to MDN about the HTML id attribute:

    This attribute's value must not contain whitespace (spaces, tabs etc.).

    That seems to be the only restriction. They have a note that HTML4 was more strict, but that's it.

    According to the spec:

    The value must not contain any ASCII whitespace.

    That means that 111 is a valid value for the HTML id attribute.

    querySelector and querySelectorAll however use CSS selectors, which are more strict:

    An ID selector consists of a #, followed by a valid 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".

    That means that #111 is not a valid CSS selector. Instead, use:

    document.querySelector('[id="111"]')
    

    To answer your question directly:

    Is "111" a valid HTML id attribute or are document.querySelector() and document.querySelectorAll() correctly throwing syntax errors?

    "111" is a valid attribute, and the syntax error are thrown correctly.