Actually there is a difference between HTML and XHTML.
As XHTML is XML the rules for XML IDs apply:
Values of type ID MUST match the Name production.
NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
Source: Extensible Markup Language (XML) 1.0 (Fifth Edition) 2.3
For HTML the following applies:
id = name [CS]
This attribute assigns a name to an element. This name must be unique in a document.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
(“.”).
Source: HTML 4 Specification, Chapter 6, ID Token