1431

What is the reason browsers do not correctly recognize:

<script src="foobar.js" /> <!-- self-closing script element -->

Only this is recognized:

<script src="foobar.js"></script>

Does this break the concept of XHTML support?

Note: This statement is correct at least for all IE (6-8 beta 2).

John
  • 10,154
  • 9
  • 79
  • 143
dimarzionist
  • 17,679
  • 4
  • 19
  • 22
  • I assume that you're talking about proper XHTML? couple of comments are still talking about XHTML – squadette Sep 16 '08 at 07:19
  • 13
    Works in Chrome and Opera – corymathews Dec 26 '08 at 17:29
  • Also, see this question: http://stackoverflow.com/questions/348736/xhtml-is-writing-self-closing-tags-for-elements-not-traditionally-empty-bad-pra – alex Apr 08 '10 at 23:21
  • 51
    Some recent version of Chrome appears to have broken this, self-closing script tags no longer work in Chrome – Adam Ness Oct 24 '10 at 17:03
  • 14
    It isn't just script tags. I don't believe self-closing div tags work either. – DOK Mar 18 '11 at 17:55
  • 8
    As of July 2011, Chrome and Firefox have this problem. "It's not a bug, it's a feature" - really annoying. – Martin Konicek Jul 24 '11 at 12:16
  • XHTML5 self-closing tags – Janus Troelsen Jun 25 '13 at 13:12
  • I only use self-closing tags for images or inputs because I know the rest can be unsupported in some browsers. – Gilly Jul 05 '13 at 09:23
  • 4
    The more general version of this was asked two days later: http://stackoverflow.com/questions/97522/what-are-all-the-valid-self-closing-elements-in-xhtml-as-implemented-by-the-maj – Ciro Santilli新疆棉花TRUMP BAN BAD Jan 01 '14 at 21:21
  • Also, in some versions of Chrome (at least mine, currently 34.0.1847.116) not only will the script in the self closing tag fail to load, but it can break script nodes defined in distant document locations (e.g. ` – Trindaz Apr 10 '14 at 02:16
  • See also: [A Detailed Breakdown of the – kenorb Aug 15 '17 at 15:23
  • Asked in 2008 and still confuses people to this day, me included. – willem Aug 06 '19 at 05:07
  • 1
    I think behind this question is an assumption that XHTML is just a well-formed subset of HTML. But in reality, XML's use of `` for self-closing tags *does not actually exist in HTML*. Tag behaviours are defined by the HTML spec. Web browsers already know e.g. that `` and`
    ` self-close and `
    ` and `
    – mwfearnley Sep 28 '19 at 21:54
  • 2
    Modern reference - companies and people are getting on board to document all this in one place, Microsoft has also endorsed this going forward as the reference to use. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script – Mark Schultheiss Nov 10 '19 at 14:35

12 Answers12

497

XHTML 1 specification says:

С.3. Element Minimization and Empty Element Content

Given an empty instance of an element whose content model is not EMPTY (for example, an empty title or paragraph) do not use the minimized form (e.g. use <p> </p> and not <p />).

XHTML DTD specifies script elements as:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
John
  • 10,154
  • 9
  • 79
  • 143
squadette
  • 7,982
  • 4
  • 26
  • 39
  • 117
    Still, “do not” isn't the same as “must not”. This is a guideline (for compatibility, as suggested by the section title), not a rule. – Konrad Rudolph Sep 16 '08 at 13:11
  • 49
    Actually, I can't find any use for this restriction :) It seems completely artificial. – squadette Sep 16 '08 at 13:17
  • 22
    The right answer was given by olavk. The Appendix C of XHTML 1.0 isn’t the reason why things are the way they are—it just how to work around the way things are. – hsivonen Oct 09 '08 at 14:36
  • 33
    It's not a normative part of specification. It's only appendix about how to deal with browsers that *do not support XHTML* – Kornel Oct 15 '08 at 20:43
  • 1
    nevertherless, browsers do understand

    notation pretty well.
    – shabunc Jul 18 '11 at 09:49
  • 13
    The problem with `` is not that the spec disallows it, but that browsers don't interpret it as "non-tag-soup" if the content type is not application/xhtml+xml. See: http://stackoverflow.com/questions/348736/is-writing-self-closing-tags-for-elements-not-traditionally-empty-bad-practice/348818#348818 @shabunc: browsers may *appear* to understand it, but what's actually happening is it's putting the content after the

    *inside* the paragraph, due to interpreting squadette's quote to mean that since

    is non-empty, it can't be self-closing. In XHTML 1.1, it *can* be self-closing.

    – Joe Jul 28 '11 at 21:07
  • [4.3. For non-empty elements, end tags are required - XHTML 1.0: The Extensible HyperText Markup Language (Second Edition)](https://www.w3.org/TR/xhtml1/#h-4.3): ... All elements other than those declared in the DTD as EMPTY must have an end tag. Elements that are declared in the DTD as EMPTY can have an end tag or can use empty element shorthand – Jeremy Kao Jul 30 '18 at 14:29
  • 1
    @JeremyKao 4.3 is not relevant here. (see the examples) Scroll down to 4.6 for the rule closer to what we are discussing. – James Curran Sep 10 '18 at 20:26
  • This is some kind of dumb IT-bureaucracy. Obviously normal people expect this to work/to be supported. Obviously parsers and interpreters could deal with this. Or at least give an error in console. When you do self-closed script, the whole page wont work and no error is shown. But then `

    ` works fine.

    – Bitterblue Sep 26 '19 at 06:51
  • @Bitterblue - There is no "bureaucracy" to blame. See greim's answer for a historical note, as to why it was done this way.. See joelhardi's answer re how to improve the situation, by sending a different mimetype. – ToolmakerSteve Oct 08 '19 at 13:41
  • Why can't at all. – David Spector May 03 '21 at 17:45
244

To add to what Brad and squadette have said, the self-closing XML syntax <script /> actually is correct XML, but for it to work in practice, your web server also needs to send your documents as properly formed XML with an XML mimetype like application/xhtml+xml in the HTTP Content-Type header (and not as text/html).

However, sending an XML mimetype will cause your pages not to be parsed by IE7, which only likes text/html.

From w3:

In summary, 'application/xhtml+xml' SHOULD be used for XHTML Family documents, and the use of 'text/html' SHOULD be limited to HTML-compatible XHTML 1.0 documents. 'application/xml' and 'text/xml' MAY also be used, but whenever appropriate, 'application/xhtml+xml' SHOULD be used rather than those generic XML media types.

I puzzled over this a few months ago, and the only workable (compatible with FF3+ and IE7) solution was to use the old <script></script> syntax with text/html (HTML syntax + HTML mimetype).

If your server sends the text/html type in its HTTP headers, even with otherwise properly formed XHTML documents, FF3+ will use its HTML rendering mode which means that <script /> will not work (this is a change, Firefox was previously less strict).

This will happen regardless of any fiddling with http-equiv meta elements, the XML prolog or doctype inside your document -- Firefox branches once it gets the text/html header, that determines whether the HTML or XML parser looks inside the document, and the HTML parser does not understand <script />.

John
  • 10,154
  • 9
  • 79
  • 143
joelhardi
  • 10,609
  • 3
  • 27
  • 38
  • 3
    Is it correct then to conclude that if you drop support for IE7, sending text/xml will get you broad browser support for ? – Chris Moschini Apr 10 '13 at 08:15
  • 7
    So, in short, will work only if your MIME type of the page is xhtml/xml. For regular text/html pages, it won't work. AND if we do try to use "xhtml/xml" MIME type, it will break IE compatibility. To summarize, Keep Calm and Use Thanks Joe ;-) – Navin Israni Dec 09 '13 at 11:54
  • 1
    Excellent explanation. Another point worth noticing is that Firefox will also have local `.html` files rendered as a tag-soup regardless of meta tags, for similar reasons. For XHTML files, Firefox will only render them accordingly if they're named `.xhtml`. – alecov Jan 08 '15 at 14:19
  • @ChrisMoschini. Probably, but use `application/xhtml+xml`, not `text/xml`. – TRiG Jul 04 '17 at 15:31
178

Others have answered "how" and quoted spec. Here is the real story of "why no <script/>", after many hours digging into bug reports and mailing lists.


HTML 4

HTML 4 is based on SGML.

SGML has some shorttags, such as <BR//, <B>text</>, <B/text/, or <OL<LI>item</LI</OL>. XML takes the first form, redefines the ending as ">" (SGML is flexible), so that it becomes <BR/>.

However, HTML did not redfine, so <SCRIPT/> should mean <SCRIPT>>.
(Yes, the '>' should be part of content, and the tag is still not closed.)

Obviously, this is incompatible with XHTML and will break many sites (by the time browsers were mature enough to care about this), so nobody implemented shorttags and the specification advises against them.

Effectively, all 'working' self-ended tags are tags with prohibited end tag on technically non-conformant parsers and are in fact invalid. It was W3C which came up with this hack to help transitioning to XHTML by making it HTML-compatible.

And <script>'s end tag is not prohibited.

"Self-ending" tag is a hack in HTML 4 and is meaningless.


HTML 5

HTML5 has five types of tags and only 'void' and 'foreign' tags are allowed to be self-closing.

Because <script> is not void (it may have content) and is not foreign (like MathML or SVG), <script> cannot be self-closed, regardless of how you use it.

But why? Can't they regard it as foreign, make special case, or something?

HTML 5 aims to be backward-compatible with implementations of HTML 4 and XHTML 1. It is not based on SGML or XML; its syntax is mainly concerned with documenting and uniting the implementations. (This is why <br/> <hr/> etc. are valid HTML 5 despite being invalid HTML4.)

Self-closing <script> is one of the tags where implementations used to differ. It used to work in Chrome, Safari, and Opera; to my knowledge it never worked in Internet Explorer or Firefox.

This was discussed when HTML 5 was being drafted and got rejected because it breaks browser compatibility. Webpages that self-close script tag may not render correctly (if at all) in old browsers. There were other proposals, but they can't solve the compatibility problem either.

After the draft was released, WebKit updated the parser to be in conformance.

Self-closing <script> does not happen in HTML 5 because of backward compatibility to HTML 4 and XHTML 1.


XHTML 1 / XHTML 5

When really served as XHTML, <script/> is really closed, as other answers have stated.

Except that the spec says it should have worked when served as HTML:

XHTML Documents ... may be labeled with the Internet Media Type "text/html" [RFC2854], as they are compatible with most HTML browsers.

So, what happened?

People asked Mozilla to let Firefox parse conforming documents as XHTML regardless of the specified content header (known as content sniffing). This would have allowed self-closing scripts, and content sniffing was necessary anyway because web hosters were not mature enough to serve the correct header; IE was good at it.

If the first browser war didn't end with IE 6, XHTML may have been on the list, too. But it did end. And IE 6 has a problem with XHTML. In fact IE did not support the correct MIME type at all, forcing everyone to use text/html for XHTML because IE held major market share for a whole decade.

And also content sniffing can be really bad and people are saying it should be stopped.

Finally, it turns out that the W3C didn't mean XHTML to be sniffable: the document is both, HTML and XHTML, and Content-Type rules. One can say they were standing firm on "just follow our spec" and ignoring what was practical. A mistake that continued into later XHTML versions.

Anyway, this decision settled the matter for Firefox. It was 7 years before Chrome was born; there were no other significant browser. Thus it was decided.

Specifying the doctype alone does not trigger XML parsing because of following specifications.

Sheepy
  • 15,393
  • 3
  • 41
  • 67
  • *"Self-closing ` – Andy E Mar 14 '15 at 19:41
  • 1
    @AndyE When you write self-closing – Sheepy Mar 16 '15 at 03:36
  • 1
    it's unclear as to the main reason the proposal was rejected as the discussion ends pretty abruptly, although breaking existing browsers with new code was one of the issues raised. I'm just pointing out that ` – Andy E Mar 16 '15 at 11:51
  • 2
    @AndyE: What you are describing is forward compatibility - the ability of old code to work with new compiler/interpreter/parser. Backward compatibility is the ability of new code to work with old compiler/interpreter/parser. So yes, backward compatibility was the issue as otherwise pages written with the new spec in mind would not work in old browsers (and yes, it's a tradition of web programming to try and make new code work in old browsers as much as possible). – slebetman Dec 09 '15 at 09:25
  • HERESY! link rel can work without self closing and self closing, but script can't. This is a matter of changing one line of DOCTYPE. Besides I as a person whose opinion does not matter, declare XHTML doctypes obsolete because html5 tags do not validate to valid xhtml. XHTML is still a fantastic tool, it allows you to create custom entities in an html page allowing you to use entities instead of full link urls, and entities instead of things that may be changed, such as names. But there is no reason to use XHTML doctype for this, it's outdated and never updated. Why is this still an issue! – Dmitry Apr 27 '16 at 01:40
  • 3
    @Dmitry The reality is, disallowing self-closed script is a one way street. As [linked](http://lists.w3.org/Archives/Public/public-whatwg-archive/2009Aug/0104.html), self-closed – Sheepy Apr 27 '16 at 03:12
  • @Sheepy Starting a deprecation period and bundling it with a "major compatibility update" would be a start. Alternatively this can be made only to impact xhtml webpages, this way well formed webpages can display both, while traditional html would only accept as it accepts now. While XHTML failed in many areas, it can still push forward to improve writing webpages for devices that are not stuck to one and only one way to write for. Without it, HTML is turning into an assembly, and a heavy one. -continued- – Dmitry Apr 27 '16 at 03:26
  • @Sheepy HTML is already mostly seen as an assembly of the web, as writing in it directly is messy and difficult to maintain. It may as well be replaced with a raw-binary format to save even more space. XHTML leverages much of these issues using patterns, extendable entities, so on that allow maintainable way to write HTML. Instead most sites I see are basically generated, and those that aren't have to struggle with the legacy gotchas like this, and the difficulty of keeping source code agree with 80 character per line limit without making code look messy. – Dmitry Apr 27 '16 at 03:28
  • @Dmitry This Q&A focus on the *why*, and may not be a proper place to discuss whether this gotcha make HTML5 obsolete, your dream of wasm for html, or why we should/should not limit our code to 80 characters (which I don't; and I develop these html "generators" as my job). – Sheepy Apr 27 '16 at 04:07
  • @Sheepy Sorry, I didn't mean to appear to say any of these things. I don't think HTML5 is obsolete; I don't dream of wasm, i'm merely mentioning the difficulties in writing beautiful hand-made HTML; and i'm quite interested in HTML generation. You're right it's not a thread on how to overcome inconsistencies in HTML, they might be too deep rooted to solve by changing the standard alone. – Dmitry Apr 27 '16 at 05:13
  • 6
    very underrated answer – Kamil Tomšík Aug 21 '16 at 09:28
  • 2
    A bit of correction: tags that appear to work as self-closed in HTML are not ones with _optional_ end tags, but ones with _prohibited_ end tags (empty, or void, tags). Tags with _optional_ end tags, like `

    ` or `

  • `, can't be 'self-closed' since they _can_ have content, so code like `

    ` is nothing more that a (malformed) start tag and the content after it, if it is allowed in this element, would end up inside it.
  • – Ilya Streltsyn May 06 '17 at 11:56