24 ms·
The case against self-closing tags in HTML
- pcdoodle 3y agoI like this and also aaron swartz rss 3.0 spec: http://www.aaronsw.com/2002/rss30 http://www.aaronsw.com/2002/rss30
- cies 3y agoSo sad the author (a hacker-activist) died in the hands of those who have sworn to protect us. Never forget! And drop all cases against Assange! RIP. https://en.wikipedia.org/wiki/Aaron_Swartz https://en.wikipedia.org/wiki/Aaron_Swartz
- timw4mail 3y agoIf a good subset of developers keep the ending slash anyway, what's the point of removing it? I used to do proper XHTML with the correct mime type. I don't anymore, but I like the syntactic ending the closing slash on a void element gives. (I also end my <p> tags, and all the rest) I really don't understand how the author thinks it is misleading.
- bunga-bunga 3y ago> I really don't understand how the author thinks it is misleading. <img/> does what you want (which is always one thing) while <picture/> does not. / is a false signal, therefore misleading.
- Someone1234 3y agoSo your argument essentially boils down to: "It is only easier to read when developers write correct HTML." That isn't as "gotcha" of a rebuttal as you think it is. It is easier to read in the common case. That's more than enough. PS - Also a lot of IDEs will flag <picture /> with "missing closing tag" or similar.
- bunga-bunga 3y agoNo, my argument is that / is completely useless and is a false signal in HTML, it really is just ignored. I never argued that it makes anything easier. An unclosed <picture> doesn't automatically become valid, but at least there's nothing suggesting that it can be done. PS - VS Code does not. Sublime Text does not.
- falcolas 3y agoThe time to rail against self closing tags is long past. No matter how good your arguments and opinions are, it's here to stay (with and without the '/>'). There are better and more meaningful windmills to tilt against. Sorry.
- jaffathecake 3y agoBut they aren't meaningful. They're specifically (as in, in the spec, and in implementations) meaningless.
- falcolas 3y agoIn which case any other windmill could only be more meaningful. :) I do get what you mean, and self-closing tags makes parsing HTML a royal pain... but it's been the status quo for decades now (self closing tags were in HTML 1.0 IIRC). It's not like they'll change it and break >90% of the internet† just to get rid of an oddity in the HTML spec. † I do literally mean >90% - self closing tags are everywhere. They're in generated HTML, they're in manually created HTML, they're created by templating languages, and so on.
- ars 3y agoHe's not asking for browsers to change, he's suggesting to developers to just stop including it because it doesn't actually do anything. It's like putting Javascript code in HTML comments - it's totally not necessary, but some people still do it.
- falcolas 3y agoIf it doesn't do anything - if it doesn't matter, then why care? I mean this quite literally. Is it worth expending any time or energy on changing habits and tooling when it doesn't matter, and will probably never matter?
- furyofantares 3y ago> If it doesn't do anything - if it doesn't matter, then why care? Because it's confusing. I've been doing this a long time and didn't actually know that /> is meaningless, and it would explain some random bugs I've worked around in the past.
- ttfkam 3y agoYet another reason to dislike JSX apparently: its parser deviates from the HTML5 spec. And at this point JSX is so well established (ossified?), fixing it would break countless sites when upgrading.
- WesolyKubeczek 3y agoIt needs to be transpiled anyway, so what could break. JSX is not HTML.
- ttfkam 3y agoThe point is that the transpiled output doesn't match the intent of the input. Did y'all not actually read the article?
- solardev 3y agoI think it's more a reason to ignore the HTML specs. They've never really meant anything and JSX is the closest thing to an actual standard that the web world has ever seen.
- jraph 3y agoI don't think so. The HTML5 parsing spec is very precise now, and browsers follow it. To my knowledge, how you parse an HTML document is now very well defined. Plus, JSX isn't even served to browsers at all. Now, I don't agree with the parent that it's wrong that JSX parses differently than HTML. They got rid of the issues caused by indentation and spacing code ending up meaning something and causing a different rendering than non spaced HTML document, which is a good thing. It could also totally be fixed if needed, you define version of your dependencies in charge of interpreting it. HTML is the "unfixable" one.
- spankalee 3y agoWhat? HTML is actually standardized by a standards body. JSX isn't close to that. There's a grammar on an old web page, that's it.
- 3y ago
- Sophira 3y agoNote that some browsers may be unable to open this page because of the use of the Brotli compression algorithm[0]! If the page looks like gobbledegook when you open it, this may be why. This excludes anybody using browser versions from before 2016, as well as unfortunately many popular terminal-based browsers. [0] https://en.wikipedia.org/wiki/Brotli https://en.wikipedia.org/wiki/Brotli
- lolinder 3y agoThis is what the Accept-Encoding header is for. I ran this HTTP request (in IntelliJ's HTTP client): GET https://jakearchibald.com/2023/against-self-closing-tags-in-html/ Accept: text/html Accept-Encoding: gzip And got back this response: HTTP/1.1 200 OK Date: Thu, 06 Jul 2023 14:39:00 GMT Content-Type: text/html; charset=UTF-8 ... Content-Encoding: gzip I tried it again with "deflate" and "identity", and in each case got back a plaintext response with no compression. Maybe your browser doesn't send the Accept-Encoding header at all? In that case, according to the spec, "If no Accept-Encoding header field is in the request, any content coding is considered acceptable by the user agent."[0] If your browser doesn't send Accept-Encoding but still relies on a specific encoding or no encoding, it's your browser that is broken, not the server. [0] https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
- SahAssar 3y agoSend no Accept-Encoding leads to an uncompessed response, so I don't think that is the parents issue.
- lolinder 3y agoHmm, I got br when I dropped the header (see below). Either way, the server's behavior matches the spec, so there's something up with the client if they're seeing nonsense. Request: GET https://jakearchibald.com/2023/against-self-closing-tags-in-html/ Accept: text/html Response: HTTP/1.1 200 OK Date: Thu, 06 Jul 2023 17:01:20 GMT Content-Type: text/html; charset=UTF-8 ... Content-Encoding: br
- michaelmior 3y ago<div /> Hello …should reformat to: <div>Hello</div> I would argue that this should probably reformat to <div></div> Hello Although this is different from how browsers would interpret it, I think it's much more likely that whoever wrote <div/> intended to have an empty div.
- jaffathecake 3y agoPrettier aims to be a reformatter only. As in, the result should be the same.
- jraph 3y agoYou have a point and it is attractive, but I think a tool that reformats HTML should not change its actual meaning, the result should render the same way as the input unless explicitly asked. The original page could have been tested and a difference would be surprising. It could be an option though.
- taeric 3y agoWait, the expectation is that <div/> some text will be interpreted as <div>some text</div> Why? I'm assuming this is "well codified" somewhere, but why?! I would understand if you can't have empty divs, but you can.
- layer8 3y agoIt’s because the trailing “/“ has zero semantics now, by definition. You can add or remove it from any tag, and it doesn’t change the meaning of your HTML. <div/> some text is thus equivalent to <div> some text which in the absence of any further tags or content is interpreted as <div> some text </div> (Note however the exception for foreign content like SVG, as noted in the article.)
- oneeyedpigeon 3y agoWhat's your actual rule here? How would you handle: <div/> some text and some more text or <div/> some text, an <img src="" />, and some more text or <div/> some <em>emphasized</em> text ??
- enriquto 3y agoSelf-closing tags are an inconsequential issue. Of actual practical consequence are optional html5 tags [0]. They allow you to write html by hand as easily as if you wrote markdown. Some graybeards even say that optional html5 tags make markdown entirely unnecessary. Thus, lists don't need closing item tags: This is correct html: <ul> <li> first <li> second <li> third </ul> Tables become uncluttered: Raw html tables <table> <tr> <td> are <td> easier <td> than <tr> <td> any <td> markdown <td> flavor </table> And you can even write the entire document in that style: <!doctype html> <title>Hello</title> <p>This is a complete conforming html document. No need for stupid html, header, body elements. They are optional! [0] https://html.spec.whatwg.org/multipage/syntax.html#optional-tags https://html.spec.whatwg.org/multipage/syntax.html#optional-...
- taeric 3y agoRaw tables are "easier than any markdown" only if you don't mind it looking completely different. My favorite simple tables look like: | are | easier | than | | any | markdown | flavor | Granted, I don't know of any that allow colspan/rowspan well. And even fewer that support newlines in a cell. Styling can also be annoying. But simple tables are surprisingly annoying in most any of these options. (I should say that I fully agree with you, btw.)
- layer8 3y agoHTML tables are easier in the sense that if the length of the cell contents changes, or you add or remove lines within a single cell, that’s easy in HTML but inconvenient in Markdown (or requires special editor support).
- taeric 3y agoFair, "easier to write." They lose heavily on the "easy to read." (And folks that recognize my table as the org-mode table know that resizing the pipes is automatic for you, such that that shortcoming is addressed. :D )
- kevincox 3y agoI think that HTML5 parsing rules were a mistake. It makes it so unnecessarily complicated to parse and emit HTML. Instead of having a generic emitter that can format any set of tags you need to understand all of the special tags and deal with it. If it was just allowing some invalid constructs it wouldn't be so bad (but you would need to deal it with reading because people will generate whatever browsers accept) but you even need to be aware of these special rules when emitting. There are tags where adding in self-closing slashes breaks the markup, they need to have a separate start and end tag even if there is no content. So every emitter needs to check this list of hardcoded rules.
- pornel 3y agoWelcome to 1999! XHTML has been created exactly for this reason, and that's even where the self-closing idea came from. HTML5 syntax hasn't been designed, it's been reverse-engineered from the mess HTML has become while the XHTML has been failing to get proper (XML parsing mode) adoption.
- SoftTalker 3y agoThe other nice thing abuot xhtml is you could generate it with xslt. So your AJAX calls (returning results as XML in those days) were easy to format for display and easy to sort, filter, and query without making another round-trip.
- arzke 3y ago> The only way you know that <input /> is acceptable and <div /> isn't, is learning and remembering which elements self-close. It sucks, but that's the way it is. People remember which elements self-close by repeatedly seeing them written as self-closing tags. So while it indeed makes no difference from the browser standpoint whether you're closing your self-closing tag or not, it can be valuable to beginners.
- jaffathecake 3y agoThere's a whole section in the article about the risk to beginners.
- arzke 3y agoWhich is the section I am quoting from.
- layer8 3y agoNo, people remember which elements self-close by remembering which elements can’t have meaningful content. In the days before XHTML, approximately nobody was confused about the distinction of which elements are self-closing and which have content.
- chrisfinazzo 3y agoYet you can still apply styles - to an extent - to most of these. Even just margin/padding will affect many of them.
- cies 3y agoI prefer not to write HTML, but have it generated by an eDSL. Elm has Html, Kotlin has kotlinx.html, but there are many more. Nice ones are generated from the W3C html spec (as XML), kotlinx.html does this for instance. This way HTML is "just code", I can put break points in, it allows for some type-safety and lets me use IDE tooling to refactor/etc.
- xp84 3y agoIt may be showing my age, but I’m a monster who loves HAML to generate my html
- cies 3y agoI loved HAML (and RoR) when I was a dyn-lang believer. I've since learned some Haskell and now believe in strong typing. This also drove me away from HAML. Kotlinx.html is pretty close being a type safe HAML.
- computomatic 3y agoThis is a fantastic article with some facts I didn’t know. I hadn’t thought about how the self-closing tag is effectively nothing more than a stylistic choice. That said, it failed to persuade me. I’d still favour the self-closing style in any style guide. At least now it would be a more informed (and better scoped) preference. Considering two style guides: - <tag> is an opening tag - </tag> is a closing tag - <tag /> is a self-closing tag Note: it remains the responsibility of the author to know which tags are self-closing. Seems more useful than: - <tag> is an opening tag or a self-closing tag - </tag> is a closing tag Admittedly, it’s subjective. That’s why any consistent guide is better than none.
- jaffathecake 3y agoBut <tag /> isn't a self-closing tag, it only works for particular tag names, so you'd have to add all of those to your ruleset. And then, when you've done that, you can just remove the "/>" bit, since it's a redundant rule.
- pornel 3y agoThe editor of the HTML5 spec calls it a talisman. It doesn't do anything, it's there to reinforce your belief.
- TheRealPomax 3y agoBut it doesn't even "work for particular names" because the `/>` part isn't what closes the element. By the time the parser has seen the sequence `<br` it already knows which element this is, because it can only be the BR element, and has already finalized the DOM node for it because that's the rule for the BR tag. The moment it sees the opening angled bracket and tag, that node is created in an already closed state. So those extra two `/>` do, in the most literal sense possible, nothing at all. They're allowed to be there for historical reason but they literally do nothing: they're treated as bytes to be ignored and the DOM parser skips over them while it looks for the next active token in order to continue building the DOM.
- deleted 3y ago
- pdw 3y agoWow, I had no idea that `<div/>` wasn't interpreted as `<div></div>`.
- SoftTalker 3y agoYeah it's been a while since I was really in the markup weeds but that surprised me also. Though now that I think about it, I think I have run into that trying to create an empty div, realizing I needed to write it as <div></div> and rolling my eyes at the "inconsistency"
- lyvxh 3y agoMe neither, possibly because JSX, Svelte etc. do actually interpret it that way, deviating from HTML.
- simonkagedal 3y agoMe neither. I was so ready to disagree with the article, but this kinda won me over.
- captainmuon 3y agoI'm pretty sure it was interpreted like that, at least in IE in the XHTML days. Between the end of the XHTML era and the beginning of HTML5 they formalized the distinction between self-closing and non-self-closing tags like <div> and <br/>. I think that was a mistake.
- bentley 3y agoYou misremember—it’s the other way around. IE never supported self‐closing arbitrary elements, because IE never supported rendering an (X)HTML page using an XML parser. Requiring the slash to self‐close, and allowing any element to be self‐closed, were features of XML that never existed in HTML. When XHTML came around, rendering it required an XML‐capable parser, signaled by the webserver serving the page with the application/xhtml+xml MIME type instead of type/html. Doing so came with a slew of other effects required by XML like hard‐erroring when markup was not well‐formed. This was a big change for both browsers and web designers, so the XHTML 1.0 spec featured a compatibility mode: since XHTML 1.0 was essentially a one‐to‐one representation of HTML 4 elements as XHTML elements, XHTML documents could be rendered with a plain HTML parser, so long as they followed various rules to look like an HTML page, such as self‐closing only elements that are self‐closable in plain HTML. To incentivize people to move to the new MIME type, the W3C made this compatibility allowance temporary and removed it from the next version, XHTML 1.1. Of course, the consequence was inevitable. Effectively nobody used XHTML 1.1, and effectively nobody used application/xhtml+xml. W3C’s insistence on promoting breaking compatibility with the overwhelming majority of the web led to its loss of control of the HTML specification to WHATWG, a coalition of browser vendors. W3C’s nascent XHTML 2.0 withered and died, and WHATWG’s desired vision for HTML5 became the new standard de jure, not just de facto.
- ape4 3y agoThe inconstancy is annoying. At the very least validators should allow self closing everywhere. https://community.adobe.com/t5/dreamweaver-discussions/new-w3c-warning-about-self-closing-tags-what-to-do/td-p/13228964 https://community.adobe.com/t5/dreamweaver-discussions/new-w...
- jt2190 3y agoThis history is not quite correct: HTML was defined in SGML originally, and that did not support self-closing tags. Pulling in a DOCTYPE header and validating with, say, the W3C validator would flag self-closing tags.
- robin_reala 3y agoThe HTML spec is bigger than the web, and consumed by other specifications produced by standards bodies like W3. So for example, ePub expects well-formed XHTML, which includes closing tags.[1] The HTML spec to this day still has XML-compatibility sections.[2][3] Of course, feel free to do what you want on the web. [1] https://www.w3.org/TR/epub-33/#sec-xhtml https://www.w3.org/TR/epub-33/#sec-xhtml [2] https://html.spec.whatwg.org/#xml https://html.spec.whatwg.org/#xml [3] https://html.spec.whatwg.org/#the-xhtml-syntax https://html.spec.whatwg.org/#the-xhtml-syntax
- Finnucane 3y agoFor ebooks, we don't rely on the browser to know what to do with sloppy code, because the reader may be not a browser. It may be a Kindle or worse. So being able to strictly validate is a benefit. Also, being able to use xml-based tools for editing and creating is a bonus.
- spankalee 3y agoPrettier won't guarantee XML well-formedness. You should use a different tool for that, or an XML pluggin for Prettier.
- minus7 3y ago`<div />` getting parsed as opening tag instead of self closing is a bug (be it in the browser or in the spec) and should be fixed
- pornel 3y agoIt's been fixed. Send Content-Type: application/xhtml+xml and it will be parsed as an empty tag. But nobody brothers to turn that on. Without an opt-in it's unfixable due to backward compatibility.
- the_mitsuhiko 3y agoWhy would it be a bug in the spec? “/“ is just a parsing error in html and is ignored.
- yankput 3y ago> I wouldn't try and write JSON so it can be parsed by a YAML parser JSON is a subset of YAML so you actually can do that. You can throw all JSONs in the world at any YAML parser and it will parse it. …except for some weird unicode issues that I don’t remember that most people don’t hit unless they intentionally try.
- raldi 3y agoI remember feeling utterly lost when my browser barfed because I typed <script src=“…”> without a closing </script> like I would for an <img> tag.
- oneeyedpigeon 3y ago<script> should probably have been superseded by <link> for external files ages ago, then you could have your self-closing tag and <script>var foo=42;</script> would still work too.
- mrspuratic 3y agoI stepped on that beartrap just last week, Chrome at least will swallow the rest of the page looking for the missing </script>. Context: bulk export of thousands of legacy CGI HTML pages using "chrome --headless" to archive to PDF. The cause was a side effect of xmlstarlet which I used to inject links for CSS and JS rendering fix ups for PDF. The result was perfectly rendered 1-page blank PDFs :/
- oneeyedpigeon 3y agoI've always found it more readable to have self-closing tags written unambiguously. It can also be useful to have HTML that you can parse as XML.
- EugeneOZ 3y ago<input> looks creepy and ugly. <input/> is easier to read and is more logical.
- jacobsenscott 3y agoUgh. I no longer know how to write html, and that's fine. I let the computer write it. I use slim/haml/whatever and let the robots track the nuances of html.
- regularfry 3y agoI think this misses a big selling point of XHTML, to be honest. It's not that you can reach for an XML parser, it's that you can reach for an XML *generator".
- jopsen 3y agoMaybe one day we can have: <!doctype html/> :)
- jefftk 3y agoThe third comment on the article is a great example of how this is widely misunderstood today: >>> Only dumb people would write <div/> and expect it to be open. Don't change the language to accomodate people who can't understand basic syntax. >> But it would be open. Is it a good language design if "only dumb people" get it right? > I actually didn't know that <div/> is open, and can't believe this is so. So no, HTML is not a good language if this is possible. This makes the definition of open and closed tags meaningless.
- Animats 3y agoHave you ever had to write an HTML5 parser, or read the spec? It's hysterical. The spec formalizes the parsing of common errors. There are rules for parsing malformed comments. There are rules for handling bad syntax. The XHTML vision was that people would write it in a XML tree editor, which takes care of the nesting and syntax. Then you can't get the syntax wrong. There are JSON tree editors like that. But everybody wanted to use text editors. Tree editors exist, but have never been popular for some reason. Org mode is probably the most popular form of tree editor. I'm surprised there isn't a move to write HTML in JSON syntax.
- marcosdumay 3y ago> I'm surprised there isn't a move to write HTML in JSON syntax. JSON doesn't support sum types, and HTML (like all of XML) is all about sum types. Besides, the quotes everywhere are a step into "more annoying", not less. So, no, I don't think that move will ever happen.
- torstenvl 3y agoThere are a number of problems here, so I apologize if my approach seems scattered. I'll start narrow and go broader. The major substantive issue with this proposal is adeptly pointed about arzke, here: https://news.ycombinator.com/item?id=36616677 https://news.ycombinator.com/item?id=36616677 Namely, using <br /> instead of <br> is a useful annotation to beginners who haven't fully internalized the rules about self-closing yet; it also, minimally, reduces cognitive load on more experienced developers, just like any other such annotation (e.g., a C comment when you skip fclose() because you're using stdin or stdout). While such annotations have no material affect on the final product, they are indispensable for beginners and externalize bookkeeping, reducing cognitive load even for more seasoned devs. As a result, there are broader implications: proposals like these make the Web a less-friendly place for beginners. I believe the "old Web" had something valuable that's been lost. The creation of things like NeoCities (and its generally positive reception on HN: https://news.ycombinator.com/item?id=33648618 https://news.ycombinator.com/item?id=33648618 ) makes me believe that view is widely shared. Proposals that make learning HTML harder, even if only slightly, run counter to these shared values. (While omitting the annotation on self-closing tags is the tiniest of tiny drops in the bucket, so is the bandwidth saved; so while my objection is vulnerable to a criticism that the danger is de minimis, so is the OP position.) Worst, though, is the strident smugness with which OP dismisses all the criticisms of his position, in his blog comments, in the related Twitter thread, and here on HN. "There's a whole section in the article about the risk to beginners" is only slightly more tactful than RTFA, but it nevertheless assumes the other commenter hasn't read the link (in violation of HN guidelines), and refuses to engage in a discussion on the merits, instead just asking for another hit on the OP's blog post. Speaking of trolling for blog hits, this post, like all but one of jaffathecake's past 30 submissions, is pure self-promotion, which is obvious when you actually go to jakearchibald.com and see that the Twitter handle there is jaffathecake, and the gmail address there is jaffathecake. "Please don't use HN primarily for promotion. It's ok to post your own stuff part of the time, but the primary use of the site should be for curiosity." https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html I vehemently disagree that HTML needs to be rid of all redundancies on the assumption that anyone reading it already has the rules about which tags are self-closing memorized and internalized. I even more strongly disagree that shameless self-promotion is within the spirit or text of HN's rules.
- deleted 3y ago[deleted]
- ttepasse 3y agoCounterpoint: There are far more XML parsers and other XML tooling than HTML(5) parsers in the world. There is a reason for that, namely the HTML5 parsing algorithm. I was always a fan of polyglot markup, a serialisation profile which is both valid HTML5 when send as text/html, well-formed XHTML when send as application/xhtml+xml and of course either when parsed in the absence of a media type. That seems to me as a good example of the first clause of Postel’s law. https://www.w3.org/TR/html-polyglot/ https://www.w3.org/TR/html-polyglot/
- lilyball 3y agoThe only thing I agree with here is that Prettier should remove the /> on tags that don't self-close, i.e. it should turn <div/> into <div>. Other than that, the use of self-closing tags is a cross between an aesthetic and a reminder of which tags self-close. I work with HTML pretty rarely, so while I can remember that <br> is self-closing, I don't necessarily remember what other tags work the same way, and the inclusion of /> in HTML I'm reading is a good reminder that it's self-closing.
- xg15 3y agoI think "foreign content" is still the weirdest state in HTML5. Outside of it, it's rather clear: Depending on the content type, you're either using the XML parser or the HTML5 parser which is just its own thing and entirely divorced from XML (and SGML). But during embedded SVG sections, you're still using the HTML5 parser, only that it temporarily pretends to read XML. I have no idea what the rules are there and what kind of subsets or supersets of XML the parser is accepting here.
- nilslindemann 3y agoI like the idea that '<', '/', '>' describe the structure, and the tag name describes the meaning of the element. I prefer to act as if html5 worked in this simple way.