EDIT: for a nice summary, look at google's html style guide. Section 3.1.7 is particularly neat [0].
[0] https://google.github.io/styleguide/htmlcssguide.html#Option...
Perhaps they were thinking of XHTML, which did require all tags because it was based on XML.
No different than having a JSX syntax error in React today
In XHTML transitional, and HTML1-4, what you'd get is browsers with divergent understandings of your DOM tree structure such that content that worked fine in one would be a horribly mangled mess (often breaking layout in difficult to read ways) in another browser.
And then I found out there were some browsers that wouldn't handle it right unless content-type headers were set up right on the server, and of course that made it an extra pain, especially on commodity hosting where you might not have that remotely under your control.
The "strict warnings"/"rendering problems crash the page" setting was also... mixed. Certainly prompted you to pinpoint the issue and fix it but that level of nag often felt unnecessarily militant after what everyone was used to.
<p>Qed.
<img src=“some_image.jpg”>
And
<p>Qed.</p>
<img src=“some_image.jpg”>
Are going to give me different results.
Furthermore, you need to know about this rule even if you do write `</p>`. If you write this:
<p>
<div>hello</div>
</p>
it is invalid HTML. This is because the paragraph is auto-closed, and then your code is equivalent to this: <p>
</p><div>hello</div>
</p>
resulting in an error because of the extra `</p>` after the `</div>`.They will indeed auto close the (first) paragraph, and also auto open a new <p> element because of the extra closing </p> tag.
Try it out by typing this in your address bar and open the inspector:
data:text/html;charset=utf-8,<!DOCTYPE html><p><div>hello</div></p>
The generated HTML (document.body.parentNode.innerHTML): <head></head><body><p></p><div>hello</div><p></p></body>
Browsers will go out of their way to produce a (valid) DOM from pretty much any string (as per the HTML5 spec). (Almost?) nothing is a syntax error. You won't get a HTML5-compliant browser to show a parse error to the user in HTML (of course, this is not the case in XHTML).edit: sorry niconii, I edited my comment under your feet.
For example, try running the following document through the W3C's HTML validator[1]:
<!DOCTYPE html>
<html lang=en>
<title>Test Document</title>
<p>
<div></div>
</p>
The HTML spec contains a list of all possible parse errors[2].[1] https://validator.w3.org/nu/#textarea
[2] https://html.spec.whatwg.org/multipage/parsing.html#parse-er...
Of course, that screams "MISTAKE" that a validator should warn you about. Like a linter that would spot missing extra parentheses for an assignment in a if condition in C-like language. It is allowed to not put the parentheses, but it is recommended to put them.
And of course, that makes "Valid HTML" (almost?) redundant (There are probably "vocabulary" errors that are possible, like a missing src attribute for an img or a missing title tag in head - don't take my words on this though).
div in p is not invalid, it's outright impossible to obtain from HTML parsing.
You can obtain this by doing this in JavaScript:
document.body.appendChild(document.createElement("p"));
document.body.firstChild.appendChild(document.createElement("div")))
Or by parsing as XHTML: data:application/xhtml+xml;charset=utf-8,<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Hello</title></head><body><p><div></div></p></body></html>
You get: document.body.innerHTML
<p xmlns="http://www.w3.org/1999/xhtml"><div/></p>
Which I realize is actually a bit scary, I go out of my way to write XHTML in the hope any error will be caught, but parsing as text/html actually produces a valid dom where parsing as XHTML won't necessarily.While the HTML parser does handle errors, to conform to the spec, document authors must not make these errors.
Here is an excerpt from the spec[1]:
> As described in the conformance requirements section below, this specification describes conformance criteria for a variety of conformance classes. In particular, there are conformance requirements that apply to producers, for example authors and the documents they create, and there are conformance requirements that apply to consumers, for example web browsers. They can be distinguished by what they are requiring: a requirement on a producer states what is allowed, while a requirement on a consumer states how software is to act.
Furthermore, a user agent is not required to correct errors, and can simply halt at the first error[2]:
> The error handling for parse errors is well-defined (that's the processing rules described throughout this specification), but user agents, while parsing an HTML document, may abort the parser at the first parse error that they encounter for which they do not wish to apply the rules described in this specification.
[1] https://html.spec.whatwg.org/multipage/introduction.html#how...
[2] https://html.spec.whatwg.org/multipage/parsing.html#parse-er...
Citing from [1]:
Earlier [SGML] HTML DTDs included the following definition for flow capturing this in a rather straightforward way:
<!ENTITY % flow "%block; | %inline;">
While HTML5 lacks it, a definition for "block content" rises again by subtracting those elements from the "flow content" category that aren't also in the "phrasing content" (inline) category.Nesting of phrasing into flow elements is about the most basic property of the HTML grammar. In SGML, the flow/phrasing hierarchy is expressed by declaring the content model of flow elements as allowing %phrasing;, where %phrasing;, like in earlier HTML DTDs, is substituted into a string such as a|abbr|... containing all phrasing elements as a name group.
For example, the element declaration for the p element is as follows:
<!ELEMENT p - O
(#PCDATA|%phrasing;)*
-(%flow_only;)>
meaning that- the content of p elements can be any sequence of text content (#PCDATA) and phrasing elements, and
- flow content isn't just forbidden in direct child content of p (via admitting %phrasing; elements only), but also isn't admitted anywhere in descendant content of p, as expressed by the -(%flow_only;) SGML exclusion exception, and
- the end-element, but not the start-element tag of p can be omitted, as declared in ps tag omission indicator - O
where the flow_only parameter entity contains block-level elements as described above, ie. flow elements that aren't also phrasing elements.
There was a time when people thought we might be able to change web development practice and browsers to something more consistent, but (a) what they chose was XHTML and (b) the benefit of switching was not there.
The `p` element in particular has pretty scary rules, but it basically boils down to "if it doesn't make sense for this to be inside a paragraph (usually because it's a block element of some kind), it ends the paragraph."
[1] https://html.spec.whatwg.org/multipage/syntax.html#optional-...
However, I also want to add to the other point here; namely, "why do this in the first place?"
Google mentions "file size optimization" in the style guide linked above, and it led to criticism on HN and elsewhere along the lines of "sure, maybe shaving off a few bytes adds up for Google, but you're not Google." However, this really isn't why I do it, and I think maybe it's poisoned the discussion a bit.
For me, it's mostly about reducing visual noise. It's not necessarily less typing if you're using an editor that auto-inserts closing tags, but I think it's harder to read with the end tags, particularly when it comes to tables. For instance, consider this table (which, if you're curious, is about Super Nintendo audio samples):
<table>
<tr><th>sample rate</th> <th>data rate</th> <th>max length</th></tr>
<tr><td>32000 Hz</td> <td>18000 byte/s</td> <td> ~3.641 s</td></tr>
<tr><td>16000 Hz</td> <td> 9000 byte/s</td> <td> ~7.282 s</td></tr>
<tr><td> 8000 Hz</td> <td> 4500 byte/s</td> <td>~14.564 s</td></tr>
</table>
And now, take a look at it without the optional end tags: <table>
<tr><th>sample rate <th>data rate <th>max length
<tr><td>32000 Hz <td>18000 byte/s <td> ~3.641 s
<tr><td>16000 Hz <td> 9000 byte/s <td> ~7.282 s
<tr><td> 8000 Hz <td> 4500 byte/s <td>~14.564 s
</table>
Personally, this is much easier for me to read and maintain. There's also much less chance of me accidentally mismatching opening and closing tags, since I've eliminated almost all of the closing tags besides </table>.On top of that, let's be honest, <html><head></head><body></body></html> is just useless boilerplate. We all know what goes in the head and what goes in the body, and I think we can all figure out where the HTML starts and ends. The browser knows all of this too, which is why all of those tags are completely optional. Not only does getting rid of that make the code less noisy, it solves the age-old problem of "should I indent the head and body or not?" (Though, in practice, I still keep <html lang=en> so that I can specify the language for people who use screen readers. </html> is just silly, though.)
Today, data tables are mostly dynamically generated, probably via accessing an API endpoint of some sort. The dev would at most write a function that would output the data inside a <table> element. But the table data itself would only be visible in the browser, it wouldn't be hardcoded into the HTML markup.
The verbose format has no advantage whatsoever, unless you are doing weird xml stuff.
It's similar to how often you see tables in Markdown.
https://www.markdownguide.org/extended-syntax/
HTML tables are similarly cumbersome, with or without closing tags. If you have a table of static information to fill in, copy/pasting from Excel into a HTML table generator and pasting the output is signficantly faster.
I'd also much rather write an HTML table by hand than a markdown one.