[HN Gopher] You are not required to close your <p>, <li>, <img>,...
___________________________________________________________________
You are not required to close your <p>, <li>, <img>, or <br> tags
in HTML
Author : jen729w
Score : 135 points
Date : 2026-01-09 20:43 UTC (2 days ago)
(HTM) web link (blog.novalistic.com)
(TXT) w3m dump (blog.novalistic.com)
| delaminator wrote:
| Go back a bit further for why.
|
| Netscape Navigator did, in fact, reject invalid HTML. Then along
| came Internet Explorer and chose "render invalid HTML dwim" as a
| strategy. People, my young naive self included, moaned about NN
| being too strict. NN eventually switched to the tag soup
| approach. XHTML 1.0 arrived in 2000, attempting to reform HTML by
| recasting it as an XML application. The idea was to impose XML's
| strict parsing rules: well-formed documents only, close all your
| tags, lowercase element names, quote all attributes, and if the
| document is malformed, the parser must stop and display an error
| rather than guess. XHTML was abandoned in 2009. When HTML5 was
| being drafted in 2004-onwards, the WHATWG actually had to
| formally specify how browsers should handle malformed markup,
| essentially codifying IE's error-recovery heuristics as the
| standard.
| Sniffnoy wrote:
| The article itself falsifies this explanation; IE wasn't
| released until August 1995. The HTML draft specs published
| prior to this already specified that these tags didn't need
| closing; these simply weren't invalid HTML in the first place.
|
| The oldest public HTML documentation there is, from 1991,
| demonstrates that <li>, <dt>, and <dd> tags don't need to be
| closed! And the oldest HTML DTD, from 1992, explicitly
| specifies that these, as well as <p>, don't need closing.
| Remember, HTML is derived from SGML, not XML; and SGML, unlike
| XML, allows for the possibility of tags with optional close.
| The attempt to make HTML more XML-like didn't come until later.
| cvcount wrote:
| I have bad memories of Netscape 4 and IE4 (I think those were
| the versions) which both allowed invalid HTML but had different
| rules for doing it. Accidentally missed off a closing table tag
| once, and one browser displayed the remainder of the page, but
| the other didn't.
| bazoom42 wrote:
| But not closing <p> etc has always been valid HTML. Back from
| SGML it was possible for closing tags to be optional (depending
| on the DTD), and Netscape supported this from the beginning.
|
| Leaving out closing tags is possible when the parsing is
| unambigous. E.g <p>foo<p>bar is unambiguous becuse p elements
| does not nest, so they close automatically by the next p.
|
| The question about invalid HTML is a sepearate issue. E.g you
| can't nest a p inside an i according to the spec, so how does a
| browser render that? Or lexical error like illegal characters
| in a non-quoted attribute value.
|
| This is where it gets tricky. Render anyway, skip the invalid
| html, or stop rendering with an error message? HTML did not
| specify what to do with invalid input, so either is legal.
| Browsers choose to go with the "render anyway" approach, but
| this lead to different outputs in different browsers, since it
| wasn't agreed upon how to render invald html.
|
| The difference between Netscape and IE was that Netscape in
| more cases would skip rendering invalid HTML, where IE would
| always render the content.
| ezequiel-garzon wrote:
| Optinal tags have always been allowed in HTML, for the simple
| if debatable reason (hence xhtml) that some humans still author
| documents by hand, knowingly skip md et al _and_ want to write
| as few characters as possible (I do!).
|
| This is clear in Tim Berners-Lee's seminal, pre-Netscape "HTML
| Tags" document [0], through HTML 4 [4] and (as you point out)
| through the current living standard [5].
|
| [0]
| https://www.w3.org/History/19921103-hypertext/hypertext/WWW/...
|
| [4] https://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.1
|
| [5]
| https://html.spec.whatwg.org/multipage/syntax.html#optional-...
| pornel wrote:
| NN did not reject invalid HTML. It could not incrementally
| render tables, while IE could. That's all.
|
| Because table layout was common, a missing </table> was a
| common error that resulted in a blank page in NN. That was a
| completely unintentional bug.
|
| Optional closing tags were inherited from SGML, and were always
| part of HTML. They're not even an error.
| neilv wrote:
| I didn't know that Navigator was ever strict, and bit funny
| story about when I complained that they hadn't been strict...
|
| Around 2000, I was meeting with Tim Berners-Lee, and I
| mentioned I'd been writing a bunch of Web utility code. He
| wanted to see, so I handed him some printed API docs I had with
| me. (He talked and read fast.)
|
| Then I realized he was reading the editorializing in my
| permissive parser docs, about how browser vendors should've put
| a big error/warning message on the window for invalid HTML.
|
| Which suddenly felt presumptuous of me, to be having opinions
| about Web standards, right in front of Tim Berners-Lee at the
| time.
|
| (My thinking with the prominent warning message that every
| visitor would see, in mid/late-'90s, was that it would've been
| compelling social pressure at the time. It would imply that
| this gold rush dotcom or aspiring developer wasn't good at Web.
| Everyone was getting money in the belief that they knew
| anything at all about Web, with little way to evaluate how much
| they knew.)
| hinkley wrote:
| Former NCSA employee here. The fuck they did. Netscape caught
| us out time and again for accepting SGML garbage that we didn't
| handle properly. It's a big part of why Netscape won that round
| of the browser wars. Such recovery then wound up in tools that
| generated web pages for you and it was all over but the crying.
| JavaScript was just the last straw. Which I tried to talk them
| into adopting but got no traction.
| osxman wrote:
| It would be nice though, to close 'm ... Makes it more readable
| and less prone to mistakes.
| bmacho wrote:
| Article actually argues/states that a lot of the times not
| closing elements is more readable. It mentions tables without a
| concrete example, but I think e.g. <table>
| <tr> <td> A1 <td> B1 <td> C1 <tr> <td> A2 <td> B2 <td>
| C2 <tr> <td> A3 <td> B3 <td> C3 </table>
|
| is valid and reads better than if the row and data elements
| were closed (and on separate rows because it would be too much
| noise otherwise) (of course the whitespaces are different, if
| they matter for some reason). For a 3x3 table 5 lines vs ~15
| lines.
| hnlmorg wrote:
| I don't think tables are human readable in any machine
| readable format, not even markdown.
|
| The problem is when you have long cells that you'd normally
| word wrap inside the cell, everything else ends up misaligned
| in your markup language. Or when you need to add styling to
| text in a cell, suddenly it's unreadable again. Or when
| there's more than a small few number of columns thus causing
| each row to word wrap inside your IDE, etc
|
| I think it makes far more sense to just acknowledge that
| tables are going to ugly, compose them elsewhere, and then
| export them to your markup language following that language's
| specification strictly.
| ZiiS wrote:
| You are also not required to indent code (in most languages);
| please do if you want me to read it though.
| dashzebra wrote:
| You can also indent with spaces and tabs at the same time,
| who's judging?
| danaris wrote:
| You _monster_.
| jpc0 wrote:
| Golang would like a word...
| hinkley wrote:
| I would like Python a lot better if the tab character had
| been marked as a syntax error. Would have solved a lot of
| bullshit.
| Quarrel wrote:
| Not in python, which is how I always discover someone is
| using tabs ..
| jeroenhd wrote:
| As long as you stay consistent with the whitespace count
| line by line, you can!
| vbezhenar wrote:
| Closing optional HTML tags just adds more ambiguity. How many
| HTMLParagraphElements here, what do you think?
| <p> text1 <p> text2
| </p> </p>
| have_faith wrote:
| Why would you nest paragraph tags?
| Hendrikto wrote:
| They are not nested, according to HTML5 parsing rules. You
| get 3 (yes, three) sibling paragraphs, including an empty
| one.
|
| There being nesting is just implied by the closing tags and
| indentation. But it is not actually there. I think this is
| the point of the example: Adding the closing tags just
| confuses the reader, by implying nesting that is not
| actually there, and even introduces a third empty
| paragraph. It might be better left out entirely.
| hnlmorg wrote:
| 2. And there's no ambiguity there, just invalid HTML because
| paragraphs aren't nestable.
| kzrdude wrote:
| It may look nested but the first p is actually closed when
| the second p starts, according to
| https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
| jchw wrote:
| Wouldn't this still result in just two paragraph
| elements? Yes, the first gets auto-closed, but I don't
| see how a third paragraph could emerge out of this.
| Surely that closing tag should just get discarded as
| invalid.
|
| edit: Indeed, it creates three: the </p> seems to create
| an empty paragraph tag. Not the first time I've been
| surprised by tag soup rules.
| hnlmorg wrote:
| Hence why I said "2" ;)
| vbezhenar wrote:
| Browser will parse that as three HTMLParagraphElements. You
| may think that's invalid HTML, but browser will parse it
| and won't indicate any kind of error.
| psychoslave wrote:
| At the end of the day, browsers have to handle most of
| the invalid atrocities thrown at it.
|
| It doesn't make the code valid according to the
| specifications.
| vbezhenar wrote:
| My point is that by closing optional tags you can
| introduce subtle bugs into your layout that might take
| some time to find and browser won't be of any help. You
| write closing tag, browser will implicitly add starting
| tag. It's better to memorise which tags are optional and
| do not close them at all.
| hnlmorg wrote:
| You can also introduce subtle bugs by not closing them.
| Or forgetting which tags can be closed and thus leaving
| the wrong ones dangling.
|
| So I think your argument here is tough to take at face
| value. It feels a lot more like you're arguing personal
| preference as fact.
| psychoslave wrote:
| Precisely, it's an added burden to remember and what
| might be skipped. The less many exception, the better.
|
| Though if a linter is formatting the whole codebase on
| its own in an homogeneous way, and someone else will deal
| with the added parsing complexity, that might feel
| okayish also to me.
|
| Generally speaking, the less clutter the better. A bit
| like with a js codebase which is semicolon free where
| possible.
|
| For pleasant experience of read and write, html in a
| simple text editor is very low quality. Pug for example
| is bringing far less clutter, though mandatory space
| indentation could be avoided with some alternative
| syntactic choices.
| hnlmorg wrote:
| > Browser will parse that as three HTMLParagraphElements
|
| Why?
|
| > You may think that's invalid HTML, but browser will
| parse it and won't indicate any kind of error.
|
| It isn't an opinion, it literally is invalid HTML.
|
| What you're responding to is an assumption that I was
| suggesting browsers couldn't render that. Which isn't
| what I claimed at all. I know full well that browsers
| will gracefully handle incorrect HTML, but that doesn't
| mean that the source is magically compliant with the HTML
| specification.
| vbezhenar wrote:
| > Why?
|
| I don't know why. Try it out. That's the way browsers are
| coded.
|
| > It isn't an opinion, it literally is invalid HTML.
|
| It matters not. You're writing HTML for browser to
| consume, not for validator to accept. And most of
| webpages are invalid HTML. This very HN page contains 412
| errors and warnings according to W3C validator, so the
| whole point of HTML validness is moot.
| hnlmorg wrote:
| > I don't know why. Try it out. That's the way browsers
| are coded.
|
| I'm not saying you're wrong, but I'd need more than that
| to be convinced. Sorry.
|
| > It matters not. You're writing HTML for browser to
| consume, not for validator to accept.
|
| It matters because you're arguing a strawman argument.
|
| We weren't discussing what a browser can render. We were
| discussing the source code.
|
| So your comment wasn't a rebuttal of mine. It was a
| related tangent or addition.
| vbezhenar wrote:
| > I'm not saying you're wrong, but I'd need more than
| that to be convinced. Sorry.
|
| So basically my point is:
|
| 1. You can avoid closing some tags, letting browser to
| close tags for you. It won't do any harm.
|
| 2. You can choose to explicitly close all tags. It won't
| do anything for valid HTML, but it'll introduce subtle
| and hard to find DOM bugs by adding empty elements.
|
| So you're trying to improve HTML source readability by
| risking to introduce subtle bugs.
|
| If you want to do that, I'd recommend to implement HTML
| validation for build or test pipeline at least.
|
| Another alternative is to use HTML comments to close
| tags, as this closing tag is supposed to be
| documentation-only and won't be used by browser in a
| proper code.
| hnlmorg wrote:
| I get your point, but again, that's not relevant to the
| point I was making.
|
| You posted a terse comment with some HTML. I responded
| specifically about that comment and HTML. And you're now
| elaborating on things as a rebuttal to my comment despite
| the fact that wasn't the original scope of my comment.
|
| Another example of that is how you've quoted my reply to
| the 2 vs 3 elements, and then answered a completely
| different question (one I didn't even ask).
|
| I don't think you're being intentionally obtuse but it's
| still a very disingenuous way to handle a discussion.
| allreduce wrote:
| > You're writing HTML for browser to consume, not for
| validator to accept.
|
| I'm not a web programmer, but shouldn't one program
| against the specified interface instead of some edge case
| behavior of an implementation?
| LorenzA wrote:
| >Why?
|
| Because the second open p-tag closes the first p-tag and
| then the last closing p has no matching starting p-tag
| and creates one thus resulting in 3 p-elements.
|
| > It isn't an opinion, it literally is invalid HTML.
|
| the only "invalid" part is the last closing p.
| urbandw311er wrote:
| Excellent catch
| b2ccb2 wrote:
| That is invalid syntax. Only phrasing content is allowed the
| p element (https://developer.mozilla.org/en-
| US/docs/Web/HTML/Guides/Con...)
| jeroenhd wrote:
| The second <p> is not inside of the first. The first <p>
| closes when the second <p> is encountered.
|
| The syntax is invalid, but that's because the final </p>
| has no opening <p> that it can close.
| psychoslave wrote:
| This is invalid html, p tag can be nested in a p tag.
| Hendrikto wrote:
| Even though it arguably should be, according to HTML5
| parsing rules, this is not invalid. It is just interpreted
| differently from what most people would probably expect.
|
| I think this is the point of the example, afaiui: The
| closing tags don't clarify anything, quite the contrary,
| actually. They serve only to confuse the reader.
| carlosjobim wrote:
| HTML is more content than programming logic, so it shouldn't be
| indented.
| nh43215rgb wrote:
| Please just close them though.
| runarberg wrote:
| Needs a (2017) in the title.
|
| This may have been relevant 9 years ago, but today, just pick and
| auto-formatter like prettierjs and have it close these tags for
| you.
| imiric wrote:
| The author has a point, but I object to this mischaracterization:
|
| > XHTML, being based on XML as opposed to SGML, is notorious for
| being author-unfriendly due to its strictness
|
| This strictness is a moot point. Most editors will autocomplete
| the closing tag for you, so it's hardly "unfriendly". Besides, if
| anything, closing tags are reader-friendly (which includes the
| author), since they make it clear when an element ends. In
| languages that don't have this, authors often add a comment like
| `// end of ...` to clarify this. The article author even
| acknowledges this in some of their examples ("explicit end tags
| added for clarity").
|
| But there were other potential benefits of XHTML that never came
| to pass. A strict markup language would make documents easier to
| parse, and we wouldn't have ended up with the insanity of parsing
| modern HTML, which became standardized. This, in turn, would have
| made it easier to expand the language, and integrate different
| processors into the pipeline. Technologies like XSLT would have
| been adopted and improved, and perhaps we would have already had
| proper HTML modules, instead of the half-baked Web Components we
| have today. All because browser authors were reluctant to force
| website authors to fix their broken markup. It was a terrible
| tradeoff, if you ask me.
|
| So, sure, feel free to not close HTML tags if you prefer not to,
| and to "educate" everyone that they shouldn't either. Just keep
| it away from any codebases I maintain, thank you very much.
|
| To be fair, I don't mind not closing empty elements, such as
| `<img>` or `<br>`. But not closing `<p>` or `<div>` is hostile
| behavior, for no actual gain.
| recursive wrote:
| Img and br are not allowed to be closed.
| swiftcoder wrote:
| Worse, due to the aforementioned permissive error handling in
| HTML parsers, a closing </br> tag will end up inserting a
| second line break
| imiric wrote:
| Wrong.[1]
|
| > if the element is one of the void elements, or if the
| element is a foreign element, then there _may be_ a single
| U+002F SOLIDUS character ( /)
|
| If you're going to be pedantic, at least be correct about it.
|
| [1]:
| https://html.spec.whatwg.org/multipage/syntax.html#start-
| tag...
| swiftcoder wrote:
| There can't however be a separate closing tag, which is a
| reasonable interpretation of the post you are replying to
| eddyg wrote:
| You left out the rest of the spec:
|
| > On _void_ elements, it does not mark the start tag as
| self-closing but instead is unnecessary and has no effect
| of any kind. For such _void_ elements, it should be used
| only with caution -- especially since, if directly preceded
| by an unquoted attribute value, it becomes part of the
| attribute value rather than being discarded by the parser.
|
| (The _void_ elements are listed here:
| https://developer.mozilla.org/en-
| US/docs/Glossary/Void_eleme... )
| imiric wrote:
| All of that is a far cry from elements not being
| _allowed_ to be closed. Please point to where the spec
| mentions that. MDN is not the spec.
| hnlmorg wrote:
| You close them in the same tag: <br/>
| pornel wrote:
| This syntax is ignored in HTML. The / is thrown away and
| has no effect.
|
| This non-closing talisman means that <div/> or <script/>
| are not closed, and will mess up nesting of elements.
| hnlmorg wrote:
| In HTML, yes. But I thought the OP was talking about
| XHTML?
| Finnucane wrote:
| For ebook production, you need to use xhtml, the epub standard
| is defined that way. And it is indeed useful to be able to
| treat them as xml files and use xslt and xquery, etc. with
| them.
| themafia wrote:
| Yea but it feels gross when I don't.
| patrickmay wrote:
| You just confessed to having taste.
| seydor wrote:
| Yeah but it's better for your mental sanity. It's not just a
| habit, the closure reduces the mental load and helps to keep
| track of structure in the messy world of html documents. So it is
| actually more efficient
| QuantumNomad_ wrote:
| It depends completely on how nested your HTML tags are.
|
| I hand write my HTML sometimes, and in those cases it's often
| very basic documents consisting of maybe an outer container
| div, a header and a nav with a ul of li for the navigation
| items and then an inner container div and maybe an article
| element, and then the contents are mostly p and figure elements
| and various level headings.
|
| In this case, there is no mental overhead of omitting closing
| li and closing p at the end of the line, and I omit them
| because I am allowed to and it's still readable and fine.
| renegade-otter wrote:
| Just because you can, doesn't mean you should.
| bell-cot wrote:
| Also true: You are not required to bathe IRL.
|
| (But it might be better if you make a habit of doing so.)
| card_zero wrote:
| This is ridiculous. You're genuinely applying social pressure
| to close tags. I remember when this began, drove me nuts.
| bell-cot wrote:
| An anonymous account on HN is applying social pressure?
|
| Or am I pointing out that closing tags is a human social
| issue, with aspects ranging from practical & reasonable, to
| ridiculous & widely exploited?
| gregoriol wrote:
| I get why you may not close <img> or <br> since they don't
| contain anything inside, but <p> and <li> should be closed to
| indicate the end of the content, otherwise it's shows you are
| mentally lazy and relying on some magic to do the work and guess
| what you wanted
| QuantumNomad_ wrote:
| To each their own. In simple lists for navigation menus I
| always omit closing li. There is no ambiguity on what I am
| intending even with those closing li omitted in such simple
| cases: <nav id=main-nav> <ul>
| <li><a href="/">Home</a> <li><a
| href="/hamburgers/">Hamburgers</a> <li><a
| href="/sausages/">Sausages</a> </ul> </nav>
| danaris wrote:
| The personal judgement isn't really helpful here?
|
| If you don't close your <p> and <li> tags, _you risk
| accidentally having content in the wrong place_.
|
| It's something to avoid because it can have bad consequences,
| not because it (somehow?) makes you a bad person.
| jeroenhd wrote:
| <p> indicates a new paragraph. <li> indicates a new list item.
| Unless otherwise specified, the existing paragraph/list item
| continues. There's nothing magic about any of this, it's part
| of the HTML spec.
|
| Laziness doesn't play a role. This isn't XML where you need to
| repeat yourself over and over again or abusing a bug in the
| rendering logic; it's following the definitions markdown
| language you're writing content in.
|
| If you're not too familiar with the HTML language then it's
| always a safe bet to close your tags, of course.
| weinzierl wrote:
| If I remember correctly Google's front page did this in the early
| days to save a few bytes.
| reddalo wrote:
| You're technically right, it seems like they had one single
| unclosed <p> right at the end of the page, for the copyright
| footer:
| https://web.archive.org/web/20010510221642/http://www.google...
|
| Literally saving four bytes.
| timonoko wrote:
| <p> was the only thing I knew when I constructed Finland's First
| Ever WEB-page in 1992.
|
| Correction: there was also the issue of A and O. Those were
| &AUML; and &OUML; I think.
|
| https://timonoko.github.io/alaska/index.htm
| timonoko wrote:
| On 640x480 VGA-display this page looks quite alright.
| 7bit wrote:
| > "Did you forget to close your p tags or is that on purpose?" >
| [...] > These are all adapted from real comments;
|
| If that's a comment you get, write better code. It does not
| matter to me whether closing p-tags is mandatory or optional. If
| you don't do it, I don't want you working on the same code base
| as me.
|
| This kind of knowledge makes for fun blog posts, but if people
| direct these kind of comments to me. You're obviously using your
| knowledge to just patronize and lecture people.
| nine_k wrote:
| You don't need to close these tags. But if you value your sanity
| more than saving a few bytes, you as well may close them, it's
| not an error.
| MORPHOICES wrote:
| The HTML Specification (spec) states it is possible to omit
| closing tags for certain elements when writing HTML documents. ~
|
| In fact, most web browsers now automatically insert these closing
| tags for the user.
|
| This feature has been around for many years now.
|
| However, I have found that many organizations still require that
| the closing tags be included explicitly.
|
| I am curious how other organizations determine when to use the
| "the spec allows it" as a reason to not include the closing tags.
|
| What point do developers cross from merely allowing this to being
| considered a technical debt?
|
| Have you ever utilized the feature of the specification that
| caused you a problem later?
| nubinetwork wrote:
| > Browsers do not treat missing optional end tags as errors that
| need to be recovered from
|
| Just because it worked on the one browser you tested it on,
| doesn't mean it's always worked that way, or that it will always
| work that way in the future...
|
| Every browser treats html/etc differently... I've run into css
| issues before on Chrome for android, because I was writing using
| Chrome for desktop as a reference.
|
| You'd think they should be the same because they come from the
| same heritage, but no...
| JimDabell wrote:
| > Just because it worked on the one browser you tested it on,
| doesn't mean it's always worked that way, or that it will
| always work that way in the future...
|
| All browsers have worked this way for decades. It's standard
| HTML that has been in widespread use since the beginning of the
| web. The further back you go, the more normal it was to write
| HTML in this style. You can see in this specification from 1992
| that <p> and <li> don't have closing tags at all:
|
| https://info.cern.ch/hypertext/WWW/MarkUp/Tags.html
|
| Maybe there were obscure browsers that had bugs relating to
| this back in the mid 90s, but I don't recall any from the late
| 90s onwards. Can you name a browser released this millennium
| that doesn't understand optional closing tags?
| HiPhish wrote:
| Serious question: why would you ever want to not close tags? It
| saves a couple of key strokes, but we have snippets in our
| editors, so the amount of typing is the same. Closed tags allow
| editors like Vim or automated tools to handle the source code
| easier; e.g. I can type `dit` in Vim to delete the contents of a
| tag, something that's only possible because the tag's content is
| clearly delimited. It makes parsing HTML easier because there are
| fewer syntax rules.
|
| I learned HTML quite late, when HTML 5 was already all the rage,
| and I never understood why the more strict rules of XML for HTML
| never took off. They seem so much saner than whatever soup of
| special rules and exceptions we currently have. HTML 5 was an
| opportunity to make a clear cut between legacy HTML and the
| future of HTML. Even though I don't have to, I strive to adhere
| to the stricter rules of closing all tags, closing self-closing
| tags and only using lower-case tag names.
| vbezhenar wrote:
| > why would you ever want to not close tags?
|
| Because browsers close some tags automatically. And if your
| closing tag is wrong, it'll generate empty element instead of
| being ignored. Without even emitting warning in developer
| console. So by closing tags you're risking introducing very
| subtle DOM bugs.
|
| If you want to close tags, make sure that your building or
| testing pipeline ensures strict validation of produced HTML.
| pwdisswordfishy wrote:
| > I never understood why the more strict rules of XML for HTML
| never took off
|
| Internet Explorer failing to support XHTML at all (which also
| forced everyone to serve XHTML with the HTML media type and
| avoid incompatible syntaxes like self-closing <script />),
| Firefox at first failing to support progressive rendering of
| XHTML, a dearth of tooling to emit well-formed XHTML (remember,
| those were the days of PHP emitting markup by string
| concatenation) and the resulting fear of pages entirely failing
| to render (the so-called Yellow Screen of Death), and a side
| helping of the WHATWG cartel^W organization declaring XHTML
| "obsolete". It probably didn't help that XHTML did not offer
| any new features over tag-soup HTML syntax.
|
| I think most of those are actually no longer relevant, so I
| still kind of hope that XHTML could have a resurgence, and that
| the tag-soup syntax could be finally discarded. It's long
| overdue.
| xg15 wrote:
| What I never understood was why, for HTML specifically,
| syntax errors are such a fundamental unsolvable problem that
| it's essential that browsers accept bad content.
|
| Meanwhile, in any other formal language (including JS and
| CSS!), the standard assumption is that syntax errors are
| fatal, the responsibility for fixing lies with the page
| author, but also that fixing those errors is not a difficult
| problem.
|
| Why is this a problem for HTML - and only HTML?
| nicoburns wrote:
| It's mostly historical. Browsers accepted invalid HTML for
| 10 years, there's a lot of content authored with that
| assumption that's never going to be updated, so now we're
| stuck with it.
|
| We _could_ be more strict for new content, but why bother
| if you have to include the legacy parser anyway. And the
| HTML5 algorithm brings us most of the benefits
| (deterministic parsing) of a stricter syntax while still
| allowing the looseness.
| londons_explore wrote:
| > never going to be updated, so now we're stuck with it.
|
| Try going to any 1998 web page in a modern browser...
| It's generally so broken so as to be unusable.
|
| As well as every page telling me to install flash, most
| links are dead, most scripts don't run properly
| (vbscript!?), tls versions now incompatible, etc.
|
| We shouldn't put much effort into backwards compatibility
| if it doesn't work in practice. The best bet to open a
| 1998 web page is to install IE6 in a VM, and everything
| works wonderfully.
| afavour wrote:
| The vast majority of pages from 1998 work fine today.
| VBscript was always a tiny minority of scripting. And
| link rot is an undeniable problem but that's not an issue
| with the page itself.
| Kwpolska wrote:
| You're unlikely to find a 1998-era Web page still running
| a 1998-era SSL stack. SSL was expensive (computationally
| and CA-cartel-ically), so basically banks and online
| shopping would have used SSL back then.
| bazoom42 wrote:
| Syntax errors are not fatal in CSS. CSS has detailed rules
| for how to handle and recover from syntax errors, usually
| by skipping the invalid token. This is what allows
| introducing new syntax in a backwards-compatible manner.
| barnabee wrote:
| Because HTML is designed to be written by everyone, not
| just "engineers" and we'd rather be able to read what they
| have to say even if they get it wrong.
| halapro wrote:
| It's more that it's exceedingly easy to generate bad
| X(H)ML strings especially back when you had PHP
| concatenating strings as you went. Most HTML on the web
| is live/dynamic so there's no developer to catch syntax
| errors and "make build" again.
| notahacker wrote:
| HTML is a markup language to format text, not a programming
| or data serialization language so end users have always
| preferred to see imperfectly coded or incompletely loaded
| web pages imperfectly rendered over receiving a failure
| message, particularly on 90s dialup. Same applies to most
| other markup languages.
|
| The web owes its success to having low barriers to entry
| and very quickly became a mixture of pages hand coded by
| people who weren't programmers, content produced by CMS
| systems which included stuff the content author didn't
| directly control and weren't necessarily reliable at
| putting tags into the right place, and third party widgets
| activated by pasting in whatever code the third party had
| given you. And browsers became really good at attempting to
| rendering erroneous and ambiguous markup (and for that
| matter were usually out of date or plain bad at rigidly
| implementing standards)
|
| There was a movement to serve XHTML as XML via the
| application/xhtml+xml MIME type but it never took off
| because browsers didn't do anything with it except loading
| a user-hostile error page if a closing tag was missed (or
| refusing to load it at all in the case of IE6 and older
| browsers), and if you wanted to do clever transformation of
| your source data, there were ways to achieve that other
| than formatting the markup sent to the browser as a subset
| of XML
| jasode wrote:
| _> Why is this a problem for HTML - and only HTML?_
|
| Your premise is not correct because you're not aware that
| _other data formats_ also have parsers that accept
| malformed content. Examples:
|
| - pdf files: many files with errors can be read by Adobe
| Acrobat. And code PDF libraries for developers often
| replicate this behavior so they too can also open the same
| invalid pdf files.
|
| - zip files. 7-Zip and WinRAR can open some malformed zip
| files that don't follow the official PKZIP specification.
| E.g. 7-Zip has extra defensive code that looks for a bad
| 2-byte sequence that shouldn't be there and skips over it.
|
| - csv files. MS Excel can read some malformed csv files.
|
| - SMTP email headers: Mozilla Thunderbird, MS Outlook, etc
| can parse fields that don't exactly comply with RFC 822 --
| make some guesses -- and then successfully display the
| email content to the user
|
| The common theme to the above, including HTML... _the Raw
| Content is more important than a perfectly standards-
| compliant file format_. That 's why parsers across various
| domains make best efforts to load the file even when it's
| not 100% free of syntax errors.
|
| _> Meanwhile, in any other formal language (including JS
| and CSS!), the standard assumption is that syntax errors
| are fatal,_
|
| Parsing invalid CSS is not a fatal error. Example of
| validating HTML/CSS in a job listings webpage at
| Monster.com : https://validator.w3.org/nu/?doc=https%3A%2F%
| 2Fwww.monster.c...
|
| It has CSS errors such as: Error: CSS:
| background-color: none is not a background-color value.
| From line 276, column 212; to line 276, column 215
| Error: CSS: padding: 8x is not a padding value.
|
| Job hunters in the real world want to _see the jobs_
| because the goal is to get a paycheck. Therefor, a web
| browser that didn 't show the webpage just because the
| author mistakenly wrote CSS "none" instead "transparent"
| and "8x" instead of "8px" -- would be _user hostile_
| software.
| magicalhippo wrote:
| > csv files. MS Excel can read some malformed csv files.
|
| At work we have to parse CSV files which often have mixed
| encoding (Latin-1 with UTF-8 in random fields on random
| rows), occasionally have partial lines (remainder of line
| just missing) and other interesting errors.
|
| We also have to parse fixed-width flat files where fields
| occasionally aren't fixed-width after all, with no
| discernible pattern. Customer can't fix the broken
| proprietary system that spits this out so we have to deal
| with it.
|
| And of course, XML files with encoding mismatch (because
| that header is just a fixed string that bears no meaning
| on the rest of the content, right?) or even mixed
| encoding. That's just par for the course.
|
| Just some examples of how fun parsing can be.
| dragonwriter wrote:
| > What I never understood was why, for HTML specifically,
| syntax errors are such a fundamental unsolvable problem
| that it's essential that browsers accept bad content.
|
| Because HTML is a content language, and at any given time
| the main purpose of the main engines using it will be to
| access a large array of content that is older than the
| newest revision of the language, and anything that creates
| significant incompatibilities or forces completely rewrites
| of large bodies of work to incorporate new features in a
| standard is simply not going to be implemented as specified
| by the major implementers (it will either not be
| implemented _at all_ , or will be modified), because it is
| hostile what the implementations are used for.
| alwillis wrote:
| > Meanwhile, in any other formal language (including JS and
| CSS!), the standard assumption is that syntax errors are
| fatal,
|
| In CSS, a syntax error isn't fatal. Most of the time, an
| unrecognized property causes that selector and all its
| properties to be ignored.
|
| :is() and :where() support _forgiving selector list_ [1].
|
| Only the erroneous properties are ignored; the rest work
| normally.
|
| [1]: https://drafts.csswg.org/selectors-4/#typedef-
| forgiving-sele...
| hinkley wrote:
| I was there, Gandalf. I was there 30 years ago. I was there
| when the strength of men failed.
|
| Netscape started this. NCSA was in favor of XML style rules
| over SGML, but Netscape embraced SGML leniency fully and
| several tools of that era generated web pages that only
| rendered properly in Netscape. So people voted with their
| feet and went to the panderers. If I had a dollar for every
| time someone told me, "well it works in Netscape" I'd be
| retired by now.
| pwdisswordfishy wrote:
| > It probably didn't help that XHTML did not offer any new
| features over tag-soup HTML syntax.
|
| Well, this is not entirely true: XML namespaces enabled
| attaching arbitrary data to XHTML elements in a much more
| elegant, orthogonal way than the half-assed solution HTML5
| ended up with (the data-* attribute set), and embedding other
| XML applications like XForms, SVG and MathML (though I am not
| sure how widely supported this was at the time; some of this
| was backported into HTML5 anyway, in a way that later led to
| CVEs). But this is rather niche.
| Sankozi wrote:
| Emitting correct XHTML was not that hard. The biggest problem
| was that browsers supported plugins that could corrupt whole
| page. If you created XHTML webpage you had to handle bug
| reports caused by poorly written plugins.
| bazoom42 wrote:
| Why did markdown become popular when we already have html?
| Because markdown is much easier to write by hand in a simple
| text editor.
|
| Original SGML was actually closer to markdown. It had various
| options to shorten and simplify the syntax, making it easy to
| write and edit by hand, while still having an unambiguous
| structure.
|
| The verbose and explicit structure of xhtml makes it easier to
| process by tools, but more tedious for humans.
| oneeyedpigeon wrote:
| Is it really that much easier to write `<br>` and know that
| it isn't a problem, than just write `<br />`?
| barnabee wrote:
| It's _much_ easier to have to remember fewer rules and for
| things to be ok if you get some wrong, yes.
|
| Especially for casual users of HTML.
| epgui wrote:
| Bad reasoning.
|
| "Always close your tags" is a simpler rule (and fewer
| rules, depending how you count) than "Close your tags,
| except possibly in situations A, B, C...".
| intrasight wrote:
| I've been closing my tags for 30 years and I assume that
| I will for the rest of my days. I like that it validates
| as XML. Historically I used XSLT a LOT.
| eastbound wrote:
| It triggers the linters so often. I shall keep my <input>
| tag open.
| TZubiri wrote:
| But learning about self closing tags is an additional
| rule
| wizzwizz4 wrote:
| <script /> is invalid HTML, and <img></img> is also
| invalid HTML. There's no way to avoid knowing HTML
| syntax.
| Pxtl wrote:
| Imho the real strength of markdown is it forces people to
| stick to classes instead of styling. "I want to write in red
| comic Sans" " I don't care, you can't".
|
| And markdown tables are harder to write than HTML tables.
| However, they are generally easier to read. Unless multi line
| cell.
| jbaber wrote:
| I usually just write html tables, then convert to markdown
| via pandoc. It's a crazy world we live in.
| nathankleyn wrote:
| Personally I think Markdown got _really_ popular not because
| it is easier to write but because it is easier to read.
|
| It's kind of a huge deal that I can give a Markdown file of
| plain text content to somebody non-technical and they aren't
| overwhelmed by it in raw form.
|
| HTML fails that same test.
| epolanski wrote:
| Or because it was the default in GitHub with an ad hoc
| renderer.
| stouset wrote:
| Markdown has been extremely popular since far before
| GitHub existed.
| epolanski wrote:
| Sure, but it became kind of the default with GitHub
| taking a lead position in code repository services.
| thrdbndndn wrote:
| I'm sure Markdown was already popular, but I agree with
| the OP that GitHub made it orders of magnitude more
| popular.
|
| Previously its popularity was somewhat similar to RST.
| singingbard wrote:
| People had already ditched writing HTML for years before
| Markdown came out.
|
| People were just using other markup languages like rST.
|
| Other attempts had already proven HTML to be a bad language
| for rough documentation. Someone then just needed to write
| a spec that was easy to implement and Markdown was that.
| onion2k wrote:
| In the case of <br/> and <img/> browsers will never use the
| content inside of the tag, so using a closing tag doesn't make
| sense. The slash makes it much clearer though, so missing it
| out is silly.
| jakelazaroff wrote:
| How does the slash make it clearer? It's totally inert, so if
| you try to do the same thing with a non-void tag the results
| will not be what you expect!
| onion2k wrote:
| It indicates that the content that follows is not inside of
| the tag without the reader needing to remember how HTML
| works. Tags should have either a self-closing slash, or a
| closing tag.
|
| The third way of a bare tag is where the confusion comes
| from.
| jakelazaroff wrote:
| It _doesn 't_ indicate that, though. If you write <div
| />, for example, the content that follows _is_ inside of
| the tag. So the reader still needs to remember how HTML
| works, because the slash does nothing.
| jraph wrote:
| Contrary to <img /> or <br />, <div /> is necessarily a
| mistake or intentionally misleading. The unfamiliar
| reader should not stumble upon <div /> too often. <div />
| is a bug. It's a bit like using misleading indentation in
| C-like programming languages. Yeah, it can happen, and is
| a source of bugs, but if the page is well written, the
| regularity of having everything closed, even if it's
| decorative for the spec, can help the unfamiliar reader
| who doesn't have all the parsing rules in mind.
|
| Now, we can discuss whether we should optimize for the
| unfamiliar reader, and whether the illusion of actual
| meaning the trailing slash in HTML5 can be harmful.
|
| I would note that exactly like trailing slashes,
| indentation doesn't mean anything for the parser in
| C-like languages and can be written misleadingly, yet we
| do systematically use it, even when no unfamiliar reader
| is expected.
|
| At this point, writing a slash or not and closing all the
| tags is a coding style discussion.
|
| Now, maybe someone writing almost-XHTML (closing all
| tags, putting trailing slashes, quoting all the
| attributes) should go all the way and write actual XHTML
| with the actual XHTML content type and benefit from the
| strict parser catching potential errors that can backfire
| and that nobody would have noticed with the HTML 5
| parser.
| ndiddy wrote:
| "Self-closing tags" are not a thing in HTML5. From the HTML
| standard:
|
| > On void elements, [the trailing slash] does not mark the
| start tag as self-closing but instead is unnecessary and has
| no effect of any kind. For such void elements, it should be
| used only with caution -- especially since, if directly
| preceded by an unquoted attribute value, it becomes part of
| the attribute value rather than being discarded by the
| parser.
|
| It was mainly added to HTML5 to make it easier to convert
| XHTML pages to HTML5. IMO using the trailing slash in new
| pages is a mistake. It makes it appear as though the slash is
| what closes the element when in reality it does nothing and
| the element is self-closing because it's part of a hardcoded
| set of void elements. See here for more information:
| https://github.com/validator/validator/wiki/Markup-%C2%BB-
| Vo...
| ndriscoll wrote:
| It's not a mistake if you want to be able to use XML tools
| on your HTML. It's basically no effort to make HTML also be
| valid XML so you'd might as well get the additional tooling
| compatibility and simplicity for free. For the same reason,
| it's courteous toward others.
| Hendrikto wrote:
| Self-closing tags do nothing in HTML though. They are
| ignored. And in some cases, adding them obfuscates how
| browser's will actually interpret the markup, or introduce
| subtle differences between HTML and JSX, for example.
| MarsIronPI wrote:
| Because I want my hand-written HTML to look more like markdown-
| style languages. If I close those tags it adds visual noise and
| makes the text harder to read.
|
| Besides, at this point technologies like tree-sitter make
| editor integration a moot point: once tree-sitter knows how to
| parse it, the editor does too.
| kbolino wrote:
| A lot of HTML tags never have a body, so it makes no sense to
| close them. XML has self-closing tag syntax but it wasn't
| always handled well by browsers.
|
| A p or li tag, at least when used and nested properly,
| logically ends where either the next one begins or the
| enclosing block ends. Closing li also creates the opportunity
| for nonsensical content inside of a list but not in any list
| item. Of course all of these corner cases are now well
| specified because people did close their tags sometimes.
| afavour wrote:
| > A p or li tag, at least when used and nested properly,
| logically ends where either the next one begins or the
| enclosing block ends
|
| While this is true I've never liked it.
| <p>blah<p>blah2</p>
|
| Implies a closing </p> in the middle. But
| <p>blah<span>blah2</p>
|
| Does not. Obviously with the knowledge of the difference
| between what span and p represent I understand why but in
| terms of pure markup it's always left a bad taste in my
| mouth. I'll always close tags whenever relevant even if it's
| not necessary.
| kbolino wrote:
| This interpretation of the p element implies that it
| _contains_ a paragraph. But HTML is first and foremost a
| document format, and one could just as logically conclude
| that the p element simply _starts_ a new paragraph. Under
| the latter interpretation, </p> would never exist any more
| than </hr> or </img>.
|
| In practice, modern HTML splits the difference with
| rigorous and well defined but not necessarily intuitive
| semantics.
| Pxtl wrote:
| > XML has self-closing tag syntax but it wasn't always
| handled well by browsers.
|
| So we'll add another syntax for browsers to handle.
|
| https://xkcd.com/927/
| kbolino wrote:
| I was going to respond that HTML was the original syntax
| and XML the usurper, but a comment in another thread casts
| some doubt on that version of events:
| https://news.ycombinator.com/item?id=46576844
| coffeefirst wrote:
| I would argue the stricter rules did take off, most people
| always close <p>, it's pretty common to see <img/> over
| <img>--especially from people who write a lot of React.
|
| But.
|
| The future of HTML will forever contain content that was first
| handtyped in Notepad++ in 2001 or created in Wordpress in 2008.
| It's the right move for the browser to stay forgiving, even if
| you have rules in your personal styleguide.
| Wowfunhappy wrote:
| Imagine if you were authoring and/or editing prose directly in
| html, as opposed to using some CMS. You're using your writing
| brain, not your coding brain. You don't want to think about
| code.
|
| It's still a little annoying to put <p> before each paragraph,
| but not by that much. By contrast, once you start adding
| closing tags, you're much closer to computer code.
|
| I'm not sure if that makes sense but it's the way I think about
| it.
| SoftTalker wrote:
| It's honestly no worse than Markdown, reST, or any of the
| other text-based "formats." It's just another format.
|
| Any time I have to write Markdown I have to open a cheat
| sheet for reference. With HTML, which I have used for years,
| I just write it.
| ndiddy wrote:
| > I learned HTML quite late, when HTML 5 was already all the
| rage, and I never understood why the more strict rules of XML
| for HTML never took off. They seem so much saner than whatever
| soup of special rules and exceptions we currently have.
|
| XHTML came out at a time when Internet Explorer, the most
| popular browser, was essentially frozen apart from security
| fixes because Microsoft knew that if the web took off as a
| viable application platform it would threaten Windows'
| dominance. XHTML 1.1 Transitional was essentially HTML 4.01
| except that if it wasn't also valid XML, the spec required the
| browser to display a yellow "parsing error" page rather than
| display the content. This meant that any "working" XHTML site
| might not display because the page author didn't test in your
| browser. It also meant that any XHTML site might break at any
| time because a content writer used a noncompliant browser like
| IE 6 to write an article, or because the developers missed an
| edge case that causes invalid syntax.
|
| XHTML 2.0 was a far more radical design. Because IE 6 was
| frozen, XHTML 2.0 was written with the expectation that no
| current web browser would implement it, and instead was a
| ground-up redesign of the web written "the right way" that
| would eventually entirely replace all existing web browsers.
| For example, forms were gone, frames were gone, and all
| presentational elements like <b> and <i> were gone in favor of
| semantic elements like <strong> and <samp> that made it
| possible for a page to be reasoned about automatically by a
| program. This required different processing from existing HTML
| and XHTML documents, but there was no way to differentiate
| between "old" and "new" documents, meaning no thought was given
| to adding XHTML 2.0 support to browsers that supported existing
| web technologies. Even by the mid-2000s, asking everyone to
| restart the web from scratch was obviously unrealistic compared
| to incrementally improving it. See here for a good overview of
| XHTML 2.0's failure from a web browser implementor's
| perspective: https://dbaron.org/log/20090707-ex-html
| dragonwriter wrote:
| > I never understood why the more strict rules of XML for HTML
| never took off.
|
| Because of the vast quantity of legacy HTML content, largely.
|
| > HTML 5 was an opportunity to make a clear cut between legacy
| HTML and the future of HTML.
|
| WHATWG and its living standard that W3C took various versions
| of and made changes to and called it HTML 5, 5.1, etc., to
| pretend that they were still relevant in HTML, before finally
| giving up on that entirely, was a direct result of the
| _failure_ of XHTML and the idea of a clear cut between legacy
| HTML and the future of HTML. It was a direct reaction against
| the "clear cut" approach based on experience, not an
| opportunity to repeat its mistakes. (Instead of a clear break,
| HTML _incorporated_ the "more strict rules of XML" via the XML
| serialization for HTML; for the applications where that
| approach offers value, it is available and supported and has an
| object model 100% compatible with the more common form, and
| they are maintained together rather than competing.)
| mgr86 wrote:
| I'd argue XHTML did take off and was very widely adopted for
| the first 5-10 years of the century.
| jrm4 wrote:
| This really does feel like a job for auto-complete -slash-
| Generative ai tools.
| idoubtit wrote:
| This a very verbose and confuse article. Mixing P/LI and IMG/BR
| is wrong. I think the situation could be explained with two
| points:
|
| 1. The autoclose syntax does not exist in HTML5, and a trailing
| slash after a tag is always ignored. It's therefore recommended
| to avoid this syntax. I.e write <br> instead of <br />. For
| details and a list of void elements, see
| https://developer.mozilla.org/en-US/docs/Glossary/Void_eleme...
|
| 2. It's not mandatory to close tags when the parser can guess
| where they end. E.g. a paragraph cannot contain any line-block,
| so <p>a<div>b</div> is the same as <p>a</p><div>b</div>. It
| depends on the context, but putting an explicit end tag is
| usually less error-prone.
| vbezhenar wrote:
| Putting an explicit end tag is more error-prone. It won't do
| anything for valid HTML but it'll add empty tag for invalid
| HTML. If you want to improve human readability, put end tag
| enclosed in HTML comment. At least it won't add empty elements.
| strogonoff wrote:
| There _are_ ways for not closing HTML tags to backfire in some
| scenarios.
|
| Some rules of thumb, perhaps:
|
| -- Do not omit if it is a template and another piece of HTML is
| included in or after this tag. (The key fact, as always, is that
| we all make errors sometimes--and omitting a closing tag can make
| an otherwise small markup error turn your tree into an
| unrecognisable mess.)
|
| -- Remember, the goal in the first place is readability and
| improved SNR. Use it _only_ if you already respect legibility in
| other ways, especially the lower-hanging fruit like consistent
| use of indentation.
|
| -- Do not omit if takes more than a split-second to get it.
| (Going off the HTML spec, as an example, you could have <a> and
| <p> as siblings in one container, and in that case if you don't
| close some <p> it may be non-obvious if an <a> is phrasing or
| flow content.)
|
| The last thing you want is to require the reader of your code to
| be more of an HTML parser than they already have to be.
|
| For me personally this makes omitting closing tags OK only in
| simpler hand-coded cases with a lot of repetition, like tables,
| lists, definition lists (often forgotten), and obviously void
| elements.
| blauditore wrote:
| I know some (or even the official?) JavaDoc style guidelines
| require <p> woithout closing counterparts. But to me this feels
| the same as omitting semicolins in JS -yes, xou can get away with
| it, but it's bad style in my opinion.
| layer8 wrote:
| In the context of javadoc, you can think of <p> as a paragraph
| break, just like <br> is a line break.
| chaz6 wrote:
| If I enter the following:- <p><p></p>
|
| Should the second <p> be nested or not?
| bazoom42 wrote:
| No. P elements does not nest, so this is parsed as:
| <p></p><p></p>
| 6510 wrote:
| I always thought this was funny. Practical but not the usual
| open/close order.
| aaaaa<b>aaaa<i>aaaaa</b>aaaa</i>aaaaa
|
| I just tried this! <table>
| <tr><td>aaaaa<td>bbb <tr><td>ccccccccccc<td>dddddddddd
| <tr><td>eeeeeeeeeeeeeeeee </table>
|
| Which works and is much cleaner than the usual table tag soup. It
| makes sense as on their own <td> and <tr> tags have no meaning.
| xg15 wrote:
| Whether you can or can't omit a closing element is one thing, but
| it seems like a useful thing to be able to quickly determine if
| some content is inside or outside a tag, so why complicate
| things?
|
| (This is especially relevant with "void" tags. E.g. if someone
| wrote "<img> hello </img>" then the "hello" is _not_ contained in
| the tag. You could use the self closing syntax to make this more
| obvious -- Edit: That 's bad advice, see below.)
| oneeyedpigeon wrote:
| I absolutely agree. Also, if you want to parse HTML as XML,
| it's a lot more reliable having it in a known 'good' format to
| begin with.
| mathgeek wrote:
| This is where I always end up as well. Just because you can do
| something doesn't mean you should or shouldn't.
| jakelazaroff wrote:
| The inert self closing syntax is misleading, though, because if
| you use it for a non-void element then whatever follows _will_
| be contained within the tag.
|
| e.g. how do you think a browser will interpret this markup?
| <div /> <img />
|
| A _lot_ of people think it ends up like this (especially
| because JSX works this way): <div></div>
| <img>
|
| but it's _actually_ equal to this: <div>
| <img> </div>
| xg15 wrote:
| Ah, that's true. I think the WHATWG discouraged the syntax,
| so this might be why.
| ricardobeat wrote:
| This is really easy to detect though, unlike arbitrary rules
| on what belongs on the inside of an unclosed tag.
| didip wrote:
| Early Google did not close their tags, I think it was for the
| sake of payload size?
|
| That said, your linter is going to drive you crazy if you don't
| close tags, no?
| dizzy9 wrote:
| How the mighty have fallen. A search on YouTube now pulls in
| 2.14 MB of HTML alone.
| ratsbane wrote:
| This is more of a problem with linters.
| robust-cactus wrote:
| How does all this interact with html minification? IIRC you can't
| nest p tags but you can nest li, so does browser just make
| assumptions about your intent. Is it not better to state your
| intent as clearly as possible if not for a browser, then for the
| next developer?
|
| Payload size is a moot point given gzip.
| jakelazaroff wrote:
| You cannot nest <li>. An <li> may only be a child of <ol>, <ul>
| or <menu>.
|
| https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
| jerf wrote:
| Perhaps the most distinguishing characteristic of HTML5 is that
| it specifies _exactly_ what to do with tag soup. The rules are
| worth a glance at some time, just to see how rather absurdly
| complicated they are to do the job of picking up the pieces of
| who knows how many terabytes and petabytes of garbage HTML were
| generated before they were codified in an attempt to remain
| backwards compatible with the various browsers prior to that.
| And then you 'll understand why I'm not going to even begin to
| attempt to answer your question about how browsers handle
| various tag combinations. Instead my point is only that, with
| HTML5, there is in fact a very concrete answer that is no
| longer up to the browsers trying to each individually spackle
| over the various and sundry gaps in the standards.
|
| But honestly no answer to "what does the browser do with this
| sort of thing" fits into an HN comment anymore. I'm glad
| there's a standard, but there's a better branch of the
| multiverse where the specification of what to do with bad HTML
| was written from the beginning and is much, much simpler.
| dangoodmanUT wrote:
| Considering I can't scroll down on ios safari, maybe you
| should...
| jeroenhd wrote:
| Works fine on every browser I've thrown at it. Even Gnome Web
| (WebKit) allows scrolling just fine. Sounds like a Safari bug?
| Maybe a content blocker interfering with the page?
| tannhaeuser wrote:
| Guess what, you're not required to open <html>, <head>, or <body>
| either. It all follows from SGML tag inference rules, and the
| rules aren't _that_ difficult to understand. What makes them
| appear magical is WHATWG 's verbose ad-hoc parsing algorithm
| presentation explicitly listing eg. elements that close their
| parents originally captured from SGML but having become
| unmaintained as new elements were added. This already started to
| happen in the very first revision after Ian Hickson's initial
| procedural HTML parsing description ([1]).
|
| I'd also wish people would stop calling every element-specific
| behavior HTML parsers do "liberal and tag-soup"-like. Yes WHATWG
| HTML does define error recovery rules, and HTML had introduced
| historic blunders to accomodate inline CSS and inline JS, but
| almost always what's being complained about are just SGML empty
| elements (aka HTML void elements) or tag omission (as described
| above) by folks not doing their homework.
|
| [1]: https://sgmljs.sgml.net/docs/html5.html#tag-omission (see
| also XML Prague 2017 proceedings pp. 101ff)
| pwdisswordfishy wrote:
| This is what I complain about:
|
| https://nvd.nist.gov/vuln/detail/CVE-2020-26870
|
| https://sirre.al/2025/08/06/safe-json-in-script-tags-how-not...
|
| https://bughunters.google.com/blog/5038742869770240/escaping...
|
| None of those problems exist in XHTML.
| tannhaeuser wrote:
| I guess you're replying to my comment because you were
| triggered by my last sentence. I wasn't criticizing you
| specifically, but yeah, in another comment you're writing
|
| > _It probably didn 't help that XHTML did not offer any new
| features over tag-soup HTML syntax._
|
| which unfortunately reaks of exactly the kind of roundabout
| HTML criticism that is not so helpful IMO. We have to face
| the possibility that most HTML documents have already been
| written at this point, at least if you value text by humans.
|
| The CVEs you're referencing are due to said historic blunders
| allowing inline JS or otherwise tunneling foreign syntax in
| markup constructs (mutation XSSs are only triggered by
| serialising and reparsing HTML as part of bogus sanitizer
| libs anyway).
|
| If you look at past comments of mine, you'll notice I'm
| staunchly criticizing inline JS and CSS (should always be
| placed in external "resources") and go as far as saying CSS
| or other ad-hoc item-value syntax should not even exist when
| attributes already serve this purpose.
|
| The remaining CVE is made possible by Hickson's overly
| liberal rules for what's allowed or needs escaping in
| attributes vs SGML's much stricter rules.
| modeless wrote:
| Inline JS or CSS is fine if typed directly by humans. It's
| only a problem when generated. Generated resources should
| always be in separate files.
|
| I like the flexibility of being able to make one file HTML
| apps with inline resources when I'm not generating code.
| But there should be better protections against including
| inline scripts in generated code unintentionally.
| modeless wrote:
| HTML becomes pretty delightful for prototyping when you embrace
| this. You can open up an empy file and start typing tags with
| zero boilerplate. Drop in a script tag and forget about
| getElementById(); every id attribute already defines a
| JavaScript variable name directly, so go to town. Today the
| specs guarantee consistent behavior so this doesn't introduce
| compatiblity issues like it did in the bad old days of IE6. You
| can make surprisingly powerful stuff in a single file
| application with no fluff.
|
| I just wish browsers weren't so anal about making you load
| things from http://localhost instead of file:// directly.
| Someone ought to look into fixing the security issues of
| file:// URLs so browsers can relax about that.
| circuit10 wrote:
| Wow, I had never heard of that ID -> variable feature
| modeless wrote:
| Yeah it was hard to believe when I first learned about it,
| but it's true. I think I first found out when I forgot to
| put in a getElementById call and my code still worked.
| BiteCode_dev wrote:
| Also window.document.forms gets you direct access to all
| forms, "name" automatically attach an attribute to the
| parents and "this" rebind to the current element on inline
| event handler.
|
| The DOM API may have been very messy at creation, but it is
| also very handy and powerful, especially for binding to a
| live programming visual environment with instant remote
| update capabilities.
| halapro wrote:
| Speaking of forms: form.elements.username is my preferred
| way of accessing form fields. You can also use a field
| .form prop to access its connected form. This is
| fundamental when the field exists outside <form> ;)
| eastbound wrote:
| You mean there is bidirectional binding between
| form.elements.username and the UI value? Why did we need
| React! HTML should have IFs and FOR loops...
| halapro wrote:
| It's been there since the beginning but it has several
| exceptions, like it's not available in strict mode and
| modules. Ask your ChatGPT if implied globals are right for
| you.
| chmod775 wrote:
| More specifically it becomes a property of window, which is
| the global object.
|
| So <div id="hello"> becomes accessible as window["hello"],
| which means you can just directly write hello.innerText =
| "Hi!".
|
| Since this may conflicts with any of the hundreds of other
| properties on window, it's generally not something that
| _should_ be used.
|
| Historically it wasn't too uncommon to see it, but since it
| doesn't work well with typescript, it's very rare now.
| AlienRobot wrote:
| You can make it work with typescript by declaring it as
| an HTMLElement without defining it.
| SoftTalker wrote:
| What are the security issues of file:// URLs?
| williamcotton wrote:
| fetch("file:///C:/Users/You/Documents/secrets.txt")
| vedmakk wrote:
| "Chrome wants to access 'secrets.txt'. Allow | Deny"
| williamcotton wrote:
| $ python -m http.server
| AlienRobot wrote:
| Imagine a very plausible situation. You have 1 HTML file
| at the top that wants to access hundreds of files in a
| subfolder. There is no way you can show Allow | Deny for
| every one of them. On the other hand, it's also possible
| for someone to take that file and put it in a folder like
| Documents or Downloads, so blanket allowing it access to
| siblings would allow access to all those files.
|
| This could easily be solved by some simple contract like
| "webgame.html can only access files in a webpage/
| subdirectory," but the powers that be deemed such thing
| not worth the trouble.
| SoftTalker wrote:
| As long as same-origin is enforced this is probably OK?
| I'm going to steal my own secrets?
| indigodaddy wrote:
| Love the single file html tool paradigm! See
| https://simonwillison.net/2025/Dec/10/html-tools/
|
| Opus and I have made a couple of really cool internal tools
| for work. It's really great.
| carshodev wrote:
| Yes i love quickly creating tools in a single file, if the
| tool gets really complex I'll switch to a sveltekit Static
| site. I have a default css file I use for all of them to make
| it even quicker and not look so much like AI slop.
|
| I think every dev should have a tools.TheirDomain.zzz where
| they put different tools they create. You can make so many
| static tools and I feel like everyone creates these from time
| to time when they are prototyping things. There's so many
| free options for static hosting and you can write bash deploy
| scripts so quickly with AI, so its literally just ./deploy.sh
| to deploy. (I also recommend writing some reusable logic for
| saving to local storage/indexedDB so its even nicer.)
|
| Mine for example is https://tools.carsho.dev (100%
| offline/static tools, no monetization)
| HarHarVeryFunny wrote:
| A workaround for the file:// security deny is to use a
| JavaScript file for data (initialized array) rather than
| something more natural like JSON.
|
| Apparently JavaScript got grandfathered in as ok for direct
| access!
| marcosdumay wrote:
| > Someone ought to look into fixing the security issues of
| file:// URLs
|
| If you mean full sandboxing of applications with a usable
| capability system, then yeah, someone ought to do that. But I
| wouldn't hold my breath, there's a reason why nobody did yet.
| carshodev wrote:
| I liked learning this so much that I created a VSCode
| Extension to enable goto clicking and autocomplete and errors
| for single page html files and type hover so I can properly
| use it when i am prototyping.
|
| https://marketplace.visualstudio.com/items?itemName=carsho.h.
| ..
| skobes wrote:
| Omitting <body> can lead to weird surprises. I once had some
| JavaScript mysteriously breaking because document.body was null
| during inline execution.
|
| Since then I always write <body> explicitly even though it is
| optional.
| BigTTYGothGF wrote:
| My experience with parsing html gathered from the wild is you're
| pretty much not required to do anything. "Go wild" and "have fun"
| seem to be the mottoes.
| avidphantasm wrote:
| ...but civilized people do close them.
| thrill wrote:
| You are if I'm doing your code review.
| s_ting765 wrote:
| Same with <svg> but Firefox's XML parser will not greenlight you.
| kstrauser wrote:
| I tried using XHTML when we were told, loudly and repeatedly,
| that it was the inevitable future. Thank god it wasn't.
|
| You should close your tags. It's good hygiene. It helps IDEs help
| you. But. Trust me, you do _not_ want the browser enforcing it at
| runtime, lest your idea of fun is end users getting helpful error
| messages like an otherwise blank screen saying "Invalid syntax".
|
| For fun, imagine that various browsers are not 100.00% compatible
| ("Inconceivable!"), so that it wasn't possible to write HTML that
| every browser agreed was completely valid. Now it's guaranteed
| that some of your users will get the error page, even when you're
| sure your page is valid.
|
| Conceptually, XHTML and its analogs are better. In practice,
| they're much, much worse.
| Robdel12 wrote:
| Please do, though :)
| EmilStenstrom wrote:
| To see the actual errors, just paste your HTML here and see:
| https://emilstenstrom.github.io/justhtml/playground/ - any
| parsing errors show up below the input box.
|
| Some tags do require ending tags, others do not. Personally I
| find it hard to remember which ones, so I just close things out
| of caution. That way you're always spec-correct.
| 1vuio0pswjnm7 wrote:
| I use this daily with local HTML files, specifically not closing
| <li> tags
|
| For example, I generate numbered lists of URLs something like
| <li><a href=http://example.com>http://example.com</a>
|
| This is for text-only browser
|
| If I am viewing in graphical browser I wrap the lists in <pre>
| tags
|
| I don't think I've ever closed <br> tags
| thedelanyo wrote:
| I cannot fathom writing <p> without</p> to wrap a text.
| downsplat wrote:
| You do you in terms of taste, but the article explains very
| clearly that there's nothing wrong about not closing them, as
| they are reliably auto-closed by a well-defined standard.
| lasgawe wrote:
| I never knew that. I don't know why. I've never seen this
| mentioned in a book, tutorial, or anything.
| dhosek wrote:
| The "loose" standards of HTML led to some really awful things
| happening in the early web. I remember seeing, e.g.,
| <large><li></large> item text
|
| to get a bigger bullet on a list item which worked fine in
| Netscape but broke other browsers (and since I was on OS/2 at the
| time, it was an issue for me).
|
| Really, in 2025 people should just write XHTML and better yet,
| shouldn't be generating HTML by hand at all except for borderline
| cases not handled by their tools.
| webstrand wrote:
| Unfortunately XHTML5 doesn't exist and if you try to force the
| issue, you have to re-declare all of the non-numeric HTML
| entities in your own DTD (I abandoned the idea here). I'd love
| to use XHTML, its just not viable anymore.
|
| As for generating all HTML, that's simply not possible given
| the current state (of open-source at least) WYSIWYG HTML
| editors.
| lcnmrn wrote:
| I wish HTML 6 will actually be XHTML 6.
| senfiaj wrote:
| Maybe you are not required to close, browsers are ridiculously
| tolerant to html mistakes. But do you think it would be easy to
| maintain that HTML file and not accidentally include something in
| that unclosed tag? I often format with indentation in order to
| work with the file comfortably.
|
| Also it annoys me when people are still closing tags with '/>'.
| downsplat wrote:
| Did you read the article? An unclosed <p> is not a mistake that
| the browser is tolerating, it's 100% well-defined html5
| according to spec. If your tooling can't handle the language as
| defined, maybe the problem is with the tooling.
| jihadjihad wrote:
| I didn't have any rigorous training or anything, but my
| understanding since learning HTML way back in high school was,
| like the author mentions in TFA, tags like <br> and <p> can
| simply be used "as-is" as markup and don't need the concept of
| being closed.
|
| I write virtually zero HTML anymore, but the one time this sort
| of thing comes up is in writing PR descriptions in GitHub using
| Markdown. Sometimes I want to add a <br> or two for space. I
| guess I've never stopped to notice that I never close those tags
| after adding them, or wondered why in my head it makes sense not
| to!
| BiraIgnacio wrote:
| I'd think handling these cases would be nightmare for html
| parsers.
| hk1337 wrote:
| You're not really required to with anything in HTML or to even
| use HTML, you could do everything plain text if you wanted
| notepad0x90 wrote:
| <p>some sentence here <img src="img.jpeg"/> <p> some other
| sentence.
|
| In that example, the image could be part of the first paragraph,
| as it is there, or if i moved the second <p> before the <img> it
| would be part of the second. but if I want neither, do I not have
| to close the first paragraph?
|
| Here is a demo of what i mean on this random html paste site:
| https://htmlbin.online/closetagdemo
|
| I don't know what "not required" means, but it makes a difference
| with <p> at least in my opinion. I think the author meant that if
| the succeeding element is of the same type, you don't need to
| close the previous one.
|
| But even then, this is not a good feature, browsers aren't the
| only things processing html content, any number of tooling, or
| even human readers can get confused.
___________________________________________________________________
(page generated 2026-01-11 23:01 UTC)