A few comments on your practical guide to XHTML, which is otherwise an entirely excellent document:

Firstly, you don’t make it clear that XHTML is dead, dead, dead. The HTML Standard superseded it, and although it originally contained a thing still called XHTML, it eventually retired the XHTML name due in part to confusion with XHTML 1 <https://github.com/whatwg/html/pull/2062>. And so what we have instead is XML syntax for HTML (arguably also a tad misleading due to processing differences like document.write’s absence, tagName case differences and missing features like <noscript>, which feel a bit beyond syntax differences). Honestly, browsers never truly even implemented XHTML; what they implemented was strictly more accurately an XML syntax for HTML. They only validated the XML part, never the XHTML part, and allowed HTML features absent from XHTML. By now, I’d call even XHTML 1.0 or 1.1 validation fairly worthless, given the further divergences in the HTML Standard—though I don’t know what there may be in the way of XML-syntax HTML validation to replace it.

Anyway, I’d suggest talking about HTML and XML syntax instead, since that’s been the accepted terminology for the last eight years; or at the very least a note to some such effect at the beginning of the article.

Secondly, about boolean attributes there’s another option you don’t mention: setting the attribute to an empty string, e.g. checked="", which is what empty attribute syntax is equivalent to these days. The HTML 4 and XHTML 1 DTDs specified `checked (checked) #IMPLIED`, meaning `checked="checked"` was the only valid value, with the minimised form `checked` as equivalent¹, and `checked=""` invalid, I believe. But in practice, I believe literally no one implemented it the SGML way, and so `.getAttribute("checked")` gave you an empty string on <input checked>… though serialising the element (.innerHTML of parent) in at least Firefox 4.0² turns checked="" into checked="checked".

Thirdly, it’s possibly worth noting that <noscript> doesn’t work in XML syntax.

Fourthly, maybe not really worth noting, but XML syntax isn’t actually proper XML any more: the <template> tag needs special-casing in the parser <https://html.spec.whatwg.org/multipage/xhtml.html#templateTa...>.

¹ SGML is weird. It’s not omitting the attribute value like any sane person would expect, but rather the attribute value. Given <!ATTLIST alpha beta (gamma) #IMPLIED> (“element alpha has an optional attribute named beta which has only one legal value, gamma”), the minimised form of <alpha beta="gamma"> is <alpha gamma>; <alpha beta> would be invalid. So I guess XHTML was mildly backed into a corner on the syntax. I doubt even a single user agent ever actually implemented it the SGML way, rather special-casing it; it’s documented that many HTML user agents didn’t actually support <input checked="checked">, only <input checked>.

² Downloaded from https://ftp.mozilla.org/pub/firefox/releases/ and it Just Worked. Unfortunately, I’m on x86_64 Linux without multitarch i686 set up, and 4.0 was the oldest with x86_64 builds. Shouldn’t be hard to get 1.0 running, but my curiosity wasn’t quite great enough for the effort. I was worried 4.0 would be too new, but this "" → "checked" serialisation suggests it was still weird, so ancient browsers probably do much the same.

—⁂—

Responses to other parts of your comment:

• Shell scripting was the main exception I had in mind, for unquoted strings; and they’re something you have to be careful with. Perl has barewords; and they’re typically mostly disabled as a footgun.

• I had completely forgotten <nobr> was deemed non-conforming! One of these days I should investigate more thoroughly why, and probably appeal for it to be revived and formalised. It’s a useful and semantically-valuable thing, exactly as much as <wbr>, which I think had exactly the same “this wasn’t even in any W3C HTML spec” problem as <nobr>. In the mean time, I will continue to use it from time to time, as appropriate.

• I like to type NARROW NO-BREAK SPACE between a number and a unit, if I reckon a little spacing is called for (normally I don’t).