jQuery html() and self-closing tags

Solution 1:

To clarify, this is valid HTML:

<input type="checkbox">

and this is valid XML (including XHTML):

<input type="checkbox"/>

but it is not valid HTML. That being said, most browsers will probably accept it anyway (but the document will fail validation if that means anything to you).

html() uses innerHTML. In IE and possibly other browsers this has issues because XHTML is still modeled as an HTML DOM. See Internal IE-HTML DOM still isn’t XHTML compliant.

Basically, there is very little reason to use XHTML. It's a cross browser nightmare. For a detailed synopsis as to why see XHTML - Is writing self closing tags for elements not traditionally empty bad practise?, particularly the first answer.

Solution 2:

In the era of HTML5, one might argue that <input type="checkbox"> and <input type="checkbox" /> are equally valid representations of the same void element.

While that is true, the reason innerHTML still serializes void elements without the /> is twofold:

  • A void element is a void element regardless of how you represent it to the browser. By the time the browser has constructed the element, its markup is irrelevant, and as far as the DOM is concerned, what it is is an input element of type checkbox. The only place the element's "tag" is relevant is its tagName property, and even that has its own quirk.

  • There is no reason whatsoever for a browser to begin serializing a void element with the /> syntax when HTML5 itself, by virtue of being based on HTML, not XML, doesn't require it. Doing so just because it's equally valid to use the /> syntax needlessly breaks compatibility with legacy sites for absolutely zero gain (because the presence of the /> doesn't change the meaning of the output in any way). Which brings us back to cletus's answer distinguishing between HTML markup and XHTML markup.

innerHTML, and by extension jQuery.html(), was designed to give you an HTML representation of an element's contents from the DOM. It is not designed to give you the HTML markup that the browser used to construct the element in the DOM. You cannot "fix" this because there is nothing to fix to begin with. What you need to do, is avoid relying on an element's innerHTML for anything other than perhaps the occasional debugging session.

See also: Nested <p> tag auto-closing/opening