The case against self-closing tags in HTML
jakearchibald.com
jakearchibald.com
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-...
I'm hesitating between using a fully XML compliant code to be able to automatically spot stupid mistakes thanks to the parser, or this. If I'm not validating the XML I don't see much point in writing these extra tags. It's just less data to transfer. Compression is a thing but still.
I do see one point: the version with the extra tags is closer to the actual representation of the document in the browser. You have to explain to newcomers that a full DOM with html, head and body elements will be rendered even if they are not present in the source code, with consequences for CSS and JavaScript to style and manipulate the document. The speech is just easier when the source matches the DOM.
For the missing tag endings, it requires quite deeper knowledge about parsing HTML to read a document. It's clear that it makes taking notes faster, but the code is perhaps less clear to someone who has not read it. Still a bit hesitant on this.
Nitpick: you might need <meta charset=utf8> before the title.
DMark (https://denisdefreyne.github.io/d-mark/) is the only one I've used, but IIRC there are probably ~dozens of these out there (and many eschew furniture more than DMark).
While my syntax is even lighter than this, it's reasonable and DMark seems to be very easy and enjoyable to extend. And I say this as someone who doesn't know Ruby and for whom Ruby hasn't clicked (yet?). I'll definitely have to check it out, either to adopt it or to improve my own thing, ten years later.
Thanks for mentioning it, there's taste in this design. Very nice.
I ended up writing a python parser for it (mainly just to get access to a different css parser), and the author also has a rust parser.
Found the person omitting semicolons in Javascript ;-)
I didn't like semicolon omission at first, actually now I still prefer with the semicolons and I believe ASI was a mistake, but I mostly don't care.
For the better or the worse, when I deal with HTML directly, I usually just copy the HTML pages as they are on the server and have no mandatory Javascript, if at all. It's easier, and it's also "free backup on production".
(Yeah, that's called a pretty printer, but the symmetry is nice.)
(table
(tr
(td one)
(td two)
(td three))
(tr
(td another table)
(td with more stuff)))the example s-expression matches that structure and i perceive it as the same because the first element in any list has a special meaning (in lisp itself it is the function name, while the rest are arguments)
to replicate the html5 structure in the top comment without closing tags as s-expressions i would come up with something different:
(table
(tr)
(td) one
(td) two
(td) three
(tr)
(td) another table
(td) with more stuff)To your point, I can see the opening tag as ( and the closing as ), but then that would lead to something more like:
(table
(tr
(td one
(td two
(td three
(tr
(td ...
Which really just highlights how odd it is to see the opening tags without the closing ones. Which probably goes a long way to explaining why I don't like it. :DProbably more natural to have something like:
(html
table
tr
td "one"
td "two"
tr
td "...")
In this way, you could optionally have the closing tags of /td and such. Still looks very weird to me.Sadly they have fallen out of favour.
The markup experience was super nice.
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.)
|| are easier | than |
| any | markdown | flavor |
The number of consecutive pipes would increase the colspan value. I think I also had support for rowspan but I don't remember how.The XWiki syntax [1] also supports it by letting you use HTML attributes.
|=Title 1|=(% style="background-color:yellow" %)Title 2
|(% colspan=2 %) Word 1 Word 2
Arguably more clunky and less intuitive, but more powerful I guess.(disclaimer: I work for XWiki)
[1] https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide...
(but I've also read the docs for nearly every minimal markup format I can find, so I might be misremembering... :)
Rationale - I last did HTML when Netscape Navigator/ Communicator was still around. IIRC, usual discussion among us college students was how MS IE encouraged bad programming practices by ignoring (many?) unclosed tags, whereas Netscape wasn't as forgiving.
I've not seen much HTML since then (I definitely plan to, now). Your comment brought back some fond memories. Thank you! And mind blown.
Quoting from the document you linked:
"Omitting an element's start tag in the situations described below does not mean the element is not present; it is implied, but it is still there. For example, an HTML document always has a root html element, even if the string <html> doesn't appear anywhere in the markup."
If you need XML: use XML tools.
If you need HTML: use HTML tools.
If you need XHTML... you're writing web content for IE, and IE is dead. XHTML died with it. Feel free to stick with what you know, but that's a pretty ridiculous argument for why you shouldn't use the thing that's used these days instead of the thing we used 15 years ago =)
(hot damn, 15 years. It's been longer than most folks realize).
For the record, anyone who writes `<br />` as `<br>` is...misinformed.
>Tables become uncluttered:
If I add a tr, does it nest "than" in the first row or does it move to the second row? Surely it can't nest because each tr effectively has a /tr before it.
>Raw html tables
<table>
<tr>
<td> are
<td> easier <tr><td>but ambiguous?
<td> than
<tr>
<td> any
<td> markdown
<td> flavor
</table>
I notice you closed the title, presumably because otherwise it's ambiguous as to whether the paragraph is in the title. It's so easy to make well-formed documents by closing tags intentionally rather than pushing the closing to be inferred by context by different rendering engines I can't see why you would want sloppy mark-up.In fact, the fact that implicit end tags and implicit elements are unambiguous is why they exist as a feature at all. <td> cannot contain <tr>—the idea doesn’t make sense—so <td> followed by <tr> implicitly closes the <td>. <li> can’t contain <li>, so it implicitly closes. <p> can’t contain <p>, and so on. XML doesn’t help at all here: even if you use a strict XML parser, you can make a construct like “<p><p></p></p>”, and it’ll be ostensibly “well‐formed,” but it won’t be valid HTML.
The XML way of “make everything verbose, even when it’s already unambiguous” was a late addition to the language. And it leads to surprise like what’s visible throughout this thread, such as people expecting <div /> to act like <div></div> when it really acts like <div>.
HTML is important enough that it warrants direct investment in tooling and doesn’t need the XML approach.
The idea is to make the language less context-sensitive and more consistent. It's better if the meaning of `<p>` and `<p/>` don't change based on the parent tag. Now, obviously they failed at making the semantic changes necessary to achieve the goal, but a true XML-based language would've been far simpler both for humans and computers than what we've got now. Most of the author's points are entirely valid, but the conclusion really should've been "HTML is bad."
https://html.spec.whatwg.org/multipage/syntax.html#optional-... is where these are defined. It basically says that a TD remains open until the next sibling td or the tr/tbody/table that it is in is closed.
The language is very tolerant to untidy syntax, but most people forgot about that after we went through XHTML, which is anything but.
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.And then, when you've done that, you can just remove the "/>" bit, since it's a redundant rule.
The writer of the HTML will be told off if they try to use /> on a tag that won't actually self-close, and they will also be told off if they neglect /> on a tag that self-closes.
Once written, the reader knows that a tag that ends in /> closes itself, and if it ends in > then there's definitely a closing tag somewhere.
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.
<p>A<br B</p>
<p>C</p>
To render as this: A
B
C
But instead it renders as this: A
C
The parser treats `B<` and `p` as attributes of `br`, and determines that the `<br` tag ends with the `>` at the end of line 1.If I end the `<br` with either `/>` or `>`, it parses correctly. Which means that `/>` and `>` are both considered valid endings for the `<br` tag, but you have to have one or the other and it will keep looking until it finds one.
And they should be able to get almost all of the way there by remembering one very simple rule: self-closing tags to insert something at that point in the document, open/close tags to describe the content they surround.
<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.It could be an option though.
<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. <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.) <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
?? A td element's end tag may be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element.
Edit: I don't know the "div" rules. Don't see that here.Edit2: I'm actually curious on if what I put here is wrong.
So, makes sense that the topic seems different, but it is the explanation for why a div grows to contain everything under it. For example, this is needed to know why the div in the following text closes.
<table>
<tr>
<td>Some cell
<td>Another cell
<tr>
<td>And <div>Another
<tr>
<td>With more stuff.
Right? I get that the original confusion is thinking you can make a self closing div. But the fact that it expands to cover things that come after it requires you to know about the implicit closing. Hard to understand one without understanding the other.Edit: I suppose it would be better for me to say that none of the examples on the immediate parent post are different, because none of them close the div? It isn't that the one div expands to cover everything after it, is that nothing caused it to be closed. Indeed, if those are just snippets from a document, you can't be sure that stuff that comes after it is also not included in the div.
I would tend to agree, which is why I made this suggestion. I think it's much more likely that what was meant is to insert an empty tag, even if that's not how browsers would interpret it.
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.
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.
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.
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.
Of course, feel free to do what you want on the web.
[1] https://www.w3.org/TR/epub-33/#sec-xhtml
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.
>>> 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.
The community gave up shipping strict XHTML to the browser because the breakage could happen at runtime, whereas JSX disappears (and shows errors) at build time, so you can't ship broken JSX.
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.
Then, even if you DO adhere to strict standards, they are so low level as to be useless. HTML + CSS defines a barebones, ancient layout system for simple documents -- which most of the web isn't anymore. Want to do a simple nav bar? There is no simple "nav bar" standard. You hack it by overloading a list and repositioning the components using CSS, then sprinkle in ARIA args on top of these overloaded components to tell the screen reader exactly how you decided to abuse the markup. Want to do a responsive popup modal with a scrollable table inside? You create your own recipe for tag soup, with your own media queries and wraps and scrollbar hacks and hidden elements. And every dev ends up doing this. At the level of abstraction of an actual UI, there isn't a standard, just different hacks on top of HTML. "Semantic" HTML and JSON-LD etc. all came and went. In the end you have every webpage reinventing the wheel to create the simplest of UIs, because there wasn't really a "standard", just super low level rendering primitives. There is no real system for componentization or templatization, and every server side language invented their own.
Enter JSX, which primarily gives you a more useful system of abstraction: that of components, composition, and inheritance, rather than meaningless tags like "div" or "span". This system allowed the creation of an ecosystem (as opposed to snippets) where different packages from different teams (or companies, or OSS) can interact by passing parameters/properties back and forth, something that was pretty much impossible to do when you were just overlaying HTML on itself (early jQuery libs tried to do that and ran into constant problems with clashing event handlers, z-axis issues, CSS namespace conflicts, etc.). From there you can create style and component systems (like MUI or Chakra), or roll your company's own, from which downstream app and UI designers can actual compose business applications. This was all just basic functionality offered by the likes of WinForms and Visual Studio back in the 90s or before, but which HTML never really had until JSX took over. Then from there we got an extensive ecosystem of powerful typing, transpilation (including to native and Electron), linting, etc., all built on top of simple syntax and somewhat reusable components. There's a very simple reason React took over and became the real defacto standard: It was useful. JSX outside React also sees adoption from other frameworks because it is useful.
Purity is meaningless and pointless. Whatever standards are set today will be reinvented and ignored and superseded by the next big company or movement. From Netscape to Microsoft to Meta, every major company overloaded HTML because it was (and remains) uselessly low level. CSS and JS themselves took years to be adopted and fought long wars against ActiveX, Flash, and even Canvas -- again because HTML was so limited.
JSX frees you from the underlying rendering concerns (which users don't really care about, and frankly most devs and managers don't either) in favor of UI components and useful business logic. Even if the resulting output can still be tag soup (if you don't use a good UI framework), at least it's consistent tag soup because of component reusability and inheritance. And in the best cases, it can generate much cleaner output than HTML because you start from strictly typed and strictly linted XML-like syntax instead of overloaded HTML tags and CSS overrides, giving you a degree of intra-codebase consistency that's very difficult to achieve, and inter-package interoperability that was straight on impossible in the past.
I'd argue that JSX and React are the best things to have happened to the Web since, oh, I don't know... the image map?
You must be young and not remember. IE, Firefox, and Safari were all tolerant of malformed HTML but in wildly different and sometimes utterly incompatible ways! HTML5 was like mana from heaven when it was released. It codified exactly how HTML should be parsed, especially in cases where the input was far from perfect. It is an error to handwave that away and does not validate JSX's behavior.
Speaking of which, HTML5 precedes JSX by several years. They CHOSE not to follow the HTML5 parsing standard. This means the imperfect markup you put in JSX gets a rendering offset from what is actually delivered to the browsers. Since browsers all render according to HTML5 parsing rules, JSX by definition misses the target.
To top it all off, JSX simply CAN'T fix this behavior. HTML5 parsing rules would break existing JSX-based apps.
You may love JSX, but it is unambiguously broken in this capacity. It's not about "purity". It's about consistency. And JSX fails this metric when applied to the actual web.
Even these days, compatibility is done through transpilations and automatic polyfills. JSX DOES fix that behavior because it completely abstracts it away (together with webpack, esbuild, etc.) and renders it an afterthought. You can write and think in meaningful components, not HTML soup. The build step isn't just a meaningless cost but makes a lot of the problems of the old days less relevant.
Edit: What this ecosystem allows you to do is build on top of other people's work. So one team can spend days/months just publishing polyfills and builders, another team can build components, another team builds UIs, and together they can work together to build a cross-browser, cross-platform app -- something that is relatively doable now, but was a huge undertaking in the barebones HTML days. It's only a "de facto" standard, but it did more for app development than any HTML standards body ever did. I say that because I DO remember, and how businesses struggled year after year after year not despite but because of the fake "standards" that browsers never fully followed.
(Transpilation can improve your dev experience, but you can easily get by in a pinch with the JS features that modern browsers support natively.)
Why do you thing that a specific syntax for writing createElement gives all these positives?
What do you think all of this renders down to? That's right, html, js and css. So if those are not properly standardized and working then your house of cards falls no matter how well you have built it.
Builders, polyfills, linters, components, frameworks, etc. existed before and exists independently of JSX and react.
> The underlying HTML no longer matters except to the lib maintainers.
Would you hire a frontend dev that didn't know the difference between a <head> and a <body>? A <input> and a <select>?
Even if you would (which IMO is a very bad idea), the only reason you can build anything is that there is a well standardized base, which consists of HTML, JS and CSS. If those where not as stable, standardized and consistent as they are you would not be able to build rich web apps on top.
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.
Sorry.
It's like putting Javascript code in HTML comments - it's totally not necessary, but some people still do it.
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?
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.
Other than that, I don't really care because as you mentioned it doesn't really matter. But the needless churn is a bit annoying at times, so not a bad thing to get the message out that it's a XHTML thing and doesn't matter in HTML.
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.
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.
<img/> does what you want (which is always one thing) while <picture/> does not.
/ is a false signal, therefore misleading.
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.
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.
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.
https://community.adobe.com/t5/dreamweaver-discussions/new-w...
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.
<!doctype html/>
:) <script src=“…”>
without a closing </script>
like I would for an <img> tag.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.
Kotlinx.html is pretty close being a type safe HAML.
The major substantive issue with this proposal is adeptly pointed about arzke, here: 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 ) 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
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.
Furthermore, I'm not a fan of your personal beef with Jake and think it's over the line to accuse self promotion when he's not selling a book or service or anything other than seemingly pushing an opinion.
jaffathecake has posted, on average, once per year for the past two years. Going back to his account beginning: it's five times per year.
He posts topics that are engaging (over 60 points per post for the past 30 posts, only 10 of these posts were ignored) as well as technical and usually interesting. He then has a discussion---there are certainly other blog posters who simply post and leave. I much prefer this largely posting of one's own work to people posting tangentially relevant (at best) articles from Politico or The Atlantic. Other people regularly link his posts, confirming that he has an audience on HN. He's not even reposting his old articles or posting three times in a week when a topic doesn't "catch" on the first two attempts like MANY of the karma-heavy serial posters on HN.
His comment style (aka stubbornness) probably comes from his own development experience and he doesn't see the perspective of people writing simple "gg=G" auto-indent algorithms using Python in a new world of custom HTML elements (web components) or writing regex to quickly add a property like aria-level to every tag that can contain. These might be inefficient and contrived use-cases, and he'd probably have a leg to stand on that the trailing slash isn't necessary in those two cases, and I'd like to see what that response looks like, because I tend to oscillate between using an SSG (which I despise because I find myself picking apart i18n bugs across multiple files---a task I'm doing today) and writing HTML by hand (where I find myself needing to bulk-edit with vim or sed). This---the complexity of most frameworks vs keeping it all in your head while learning why "strong" is now preferred over "b" and trying to hand-write responsive CSS---is the modern reality that is making larger-scale web development more inaccessible for tech-half-savvy folks.
I fail to see that he's selling anything. I don't see ads anywhere on his blog. He even rejects recruiters and advertising offers on his front page. If this whole blog of his is just a ploy to get people onto his other (potentially monetized) social media, he is not pushy about it AT ALL.
I don't have a personal beef. I don't know the guy.
> it's over the line to accuse self promotion
It isn't an accusation. It's an incontrovertible fact. And it violates HN guidelines.
RIP.
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
I just re-checked, though, and it loads fine in my browser now; I'm getting "Content-Encoding: gzip" back. Perhaps it was a server misconfiguration?
It's not a timing thing, I saw your post the minute it went up and tested it right away.
I will say that it was weird because at the time, I also tested loading the main page and a couple other blog posts on the site. Only this particular one, however, was an issue, and I figured it was probably an anti-hug mechanism where the site forces Brotli compression for a resource if that resource was frequently being accessed over a certain threshold.
I honestly have no idea though. It's weird. What I do know is that it wasn't just my browser - I was having a similar issue with wget, where it got back encoded Brotli data without having asked for it. (wget does support Brotli, but doesn't send an Accept-Encoding header or, it seems, decode the output unless told to specifically.) But, again, I'm not having the issue now, and as you say, not sending an Accept-Encoding header means anything goes so it's not really the same thing as how it worked on my browser.
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 curl https://jakearchibald.com/2023/against-self-closing-tags-in-html/ -v > /dev/null
gave me: > GET /2023/against-self-closing-tags-in-html/ HTTP/2
> Host: jakearchibald.com
> user-agent: curl/7.88.1
> accept: */*
>
< HTTP/2 200
< date: Thu, 06 Jul 2023 17:21:26 GMT
< content-type: text/html; charset=UTF-8
< access-control-allow-origin: *
< cache-control: max-age=180
< strict-transport-security: max-age=31536000
< vary: Accept-Encoding
< x-frame-options: DENY
< x-nf-request-id: 01H4P36X7YHZQC8TEVXAN3AXX7
< cf-cache-status: REVALIDATED
< report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=fcIbfNmFx0qEwjSBofViCahSkzz4vTSZ5tyXZpF7TEvuRsGJ8mkqo5PCX7pG1jYCJuV4a9bA%2FlJ4BA4F0dY2mLORDO%2F67OPRKT0TOaW5by%2FoUyjVIOI1Bh9pplcDXymLbgSp9Q%3D%3D"}],"group":"cf-nel","max_age":604800}
< nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< server: cloudflare
< cf-ray: 7e29862aaea23a8a-FRA
< alt-svc: h3=":443"; ma=86400
(I also tried over http1.1, gave me the same result)There's still definitely something wrong with OP's client, because the server does exactly what it's supposed to.