550 comments

[ 4.8 ms ] story [ 323 ms ] thread
“Locality of behaviour” is such a poorly defined rule. It’s just an invented name for going against separation of concerns. Calling CSS “spooky action at a distance” is a massive stretch too. Good principles here but the arguments are quite weak and could be much simpler.
The primary stated goal is “substantially widen the pool of people who can work on web software codebases.” That’s very different from typical advice for programmers.

Customization isn’t required as long as defaults work. As such the efficiency gains from CSS etc take a back seat to simplicity.

Tailwind is a build step with just as much 'spooky action at a distance'. If it wasn't, we'd just use inline CSS.

With Tailwind you're trusting a 3rd party library to abstract the CSS spec for you, and for that abstracted quasi-spec to be followed by your build configuration.

I think there are some other benefits of tailwind. Say you have a set of css classes for different components.

Then say one component on one page now needs to be styled differently.

You have 3 options: 1. Create a whole new class which duplicates much of the previous class 2. Create a smaller class which is intended to override some rules from the first class 3. Factor out the common styles into smaller classes.

All have some maintainability concerns, but taking the 3rd option to the extreme makes the problem non existent in the first place.

That’s the real strength of tailwind. Preventing a critical mass of one off styles from making your whole css setup unmanageable

Generally this makes sense to me, and if you are just dropping markup onto the page, and don't need to worry about repeating yourself when using that component, I think that works well. Definitely better than your alternatives.

But if you've encapsulated the component at all, you're going to need to manage that variant somehow. You can't just have an 'extra tailwind classes' prop, since you can't ensure your overrides will take precedence.

Why not expose the component's styles via component-level tokens referenced through css variables? Then your new variant is a single css class on the component root that sets any new component token values that are then loaded by the component's existing css.

I’m not entirely sure what you mean by component-level tokens, but it sounds like tailwind’s themes do what you’re saying.

Most of tailwind’s classes use css variables under the hood, so setting some of those variables in a class and apply thing that class to the top level element of a component will do the trick.

But you could have an “extraClasses” prop with tailwind. Classes that appear later in a class attribute take precedence over one’s that appear earlier.

I also thing it’s possible to mark tailwind classes as important, though I don’t like doing that.

A component level token would be if your `myCard` component populated all of it's styles with component-specific css-variables, e.g. "myCard-bg", "myCard-padding". It's basically defining the styling api for your component. If you have a new variant that needs to style another property, then you should probably extend your component's style api accordingly (by defining a new component token and providing the default). As I say, I haven't yet used this approach, but it does make some sense to me. It's also useful if you're designing components across tech, targeting other style languages besides CSS.

>Classes that appear later in a class attribute take precedence over one’s that appear earlier.

This would be news to me, and it doesn't look like that's the case in TW, based on some experimenting at play.tailwindcss.com. If there are 2 classes on an element with rules that resolve to the same priority and define the same css styles, the last CSS rule to be parsed wins. Presumably you don't have control over that in TW.

The Salesforce Lightning Design System makes extensive use of this technique; they call them "styling hooks". https://www.lightningdesignsystem.com/platforms/lightning/st...
Is Lightning primarily web components? That would make sense, since css vars penetrate the shadow dom, so with this approach there's no need to mess with loading your css into the component's shadow dom.
Inline CSS is a total anti-pattern apart from the absolute most basic pages IMO.

There is no harm in a plain CSS file, and applying classes at the element level in the HTML.

If you put in-line CSS in the HTML is not only leads to severe duplication, but is also a maintenance nightmare if you want to change anything. It works fine if all you are changing is a colour or whatever, but often there are margins, paddings, letter spacings, font sizes etc etc which lead to quite a lot of extra crap in each element on your page. Repeating those all over each if your HTML files is a real burden. Just use a single CSS file with sensibly named classes - it doesn't need to be sass or anything, just plain CSS is fine.

> Just use a single CSS file with sensibly named classes

IMO you no longer need an intelligent naming philosophy for CSS classes due to how far CSS has come.

Well the point I was trying to make was to not do what the article says and name your class e.g. "green", but instead to name it something more sensible like "approved" or "updated" or something about the semantic nature of the style, rather than what the style actually is.

The reasoning is that maybe today it is just "green" but then what if one day the color in the CSS is changed, and it is not actually green anymore? You now either need to change the CSS class name everywhere, or leave it as "green" and confuse everyone because it is actually blue on-screen? This only scratches the surface - there are all manner of other considerations to think about (different display/print medias, dark/light preferences, HCM etc)

The core argument for tailwind is that it won't just be "make the approved text white on blue instead of white on green". Maybe you'll get "make the approved text a bubble with a checkmark on the left and make the title two lines where the second line is ..."

Frequently the change needed requires changing the html as well as the css (or maybe awkward advanced css). So you may as use a library/framework that lets you write an Approved component. At that point it's better to have the css and html for the Approved component in its own file as when you're updating the style you'll need to change some mixture of the html and css.

Without components tailwind is probably a bad choice.

Exactly. Classes, even for the simplest styling tasks, have been replaced by components.
Could you expand on this? Class names in CSS are just as important, if not moreso, than naming variables in typical programming.

Back in the late 90s and early 2000s, the dominant ideology is to use semantic class names, e.g. ".sidebar" instead of ".blue_bar" or similar. Essentially, don't describe how something looks with its name.

Even when building JS apps, I use CSS classes semantically with ".selected" ".menubar", etc.

I am interested in reading your philosophy on CSS classes.

The exception is when using a framework which isolates CSS at the component level, in which case your class names don’t matter anywhere near as much because you’ll only ever see them alongside the corresponding HTML.
Can't say I'm familiar with this type of webdev. How is the CSS isolated at a 'component' level? Is that not what selectors already do? I'm having trouble picturing how this is built or how it works.

Traditionally you put your template HTML or just HTML in one place, CSS in another, and JS in yet another, then tie them together via <style> and <script>. Are you saying there are frameworks that tie HTML and CSS together into the same unit? That is rather strange to me.

In such an environment, do people decide on no structure for their class names? I'd still want reusable CSS in such a situation.

It’s quite a common pattern in modern frontend frameworks. Each component includes just the CSS required for that component (plus any global styles). At built time, the bundler will generate unique class names for each of the HTML elements in the component and output an optimized CSS bundle matching those unique class names.

It definitely adds extra complexity in the build step, and the resultant randomly generated class names aren’t very nice aesthetically.

However, this approach allows you to read and modify the CSS, HTML and JS that affect a component all in the same place, instead bouncing around between different files. It also avoids the problem of naming (and remembering) globally scoped CSS selectors, and generally results in less CSS over the wire.

It’s hard for me not to see Tailwind as using the class attribute to reproduce the style attribute - burying your html tags under a pile of css classes doesn’t feel that much different than defining those styles inline.
Only people who haven't used tailwind say this. A lot of tailwind classes aren't singular styles but a composite of style attributes and mostly define behaviours rather than just expose a single CSS attribute. And a lot of that behaviour is applying styles on hover, on media queries, on grouped elements and other extremely common user actions, none of which are possible with inline styles
The styles are already coupled to the component anyway, so what's your problem with putting them in the markup? The alternative is making up arbitrary class names and putting the styles in a separate file: now you've added an extra layer of mapping that the developer after you has to grok.
People don’t seem to mind the 7 layers of mapping between their markup and HTML, why are styles different? I find that much more of a problem when it comes to understanding what’s happening for the average dev.
Problems are multidimensional.

If we look at HTML as a document / presentation language, we cannot deny styling. CSS is not only styling, but also adds animation.

In any case, CSS can be seen as aspect oriented programming.

The real problem described here is the lack of great tooling across languages / frameworks.

(coming from a C# shop with too many interfaces) I think it's a natural counter-reaction to overly abstracted systems.

If "making the red-bouncy-plonk button instead become the blue-wobble-thunk button" requires chasing through a maze of 3-to-7 interfaces and classes to find which classes need new implementations and which can be reused... Suddenly what sounded like a 10 minute change becomes half a day of swearing under your breath at either the compiler or the previous engineer.

Sure, abstract things, but make sure there's also a way to bundle behavior together in one common spot, so I don't have to touch 6 files to update one component.

https://htmx.org/essays/locality-of-behaviour/#conflict-with...

> “Locality of behaviour” is such a poorly defined rule.

And "separation of concerns" isn't?

What should be separated? Along what lines? How do we determine these lines? When does it make sense to pull some concerns out into another class/framework/markup/whatever? When does it make more sense to leave things stuck together?

The answer is: "It depends".

Not separating anything leads to spaghetti. Separating as much as possible, all the time, everywhere, leads to overly abstracted code that is easily as hard to maintain as spaghetti.

Yep. I've said this often but whatever:

JS, CSS, and HTML aren't concerns, they are technologies that have cross-cutting concerns.

I want to agree with this based on the title, but why would you do something like this:

    <div class="bg-green" onlick="this.classList.add('green')">Click me</div>
if you're already using React? Yes the React code is a lot more verbose and has a bunch of "cruft" for lack of a better word. But you're already using it for the rest of your site, so you should (IMO) continue using it rather than mixing and matching approaches.
I don't think you'd mix in React with this approach.
Isn't it much easier to know you're going to use React (or Svelte or Vue or anything else) and just start there? Starting a build in HTML-first only to bolt on a JS framework after the fact seems like a lot of wasted effort.
The whole point of this essay is to encourage developers to avoid heavy frameworks like React, Vue, etc and use "lightweight" tools, including vanilla JS and native HTML features, instead.
Sure, I'm just talking about that middle ground where you're trying to go with this approach and find that you now need a bunch of JS framework features.
are you trolling? 10 people in this thread have already explained that the point is to avoid using a heavy framework, yet you keep insisting that one is necessary.
I think the GP is referring to when people misunderstand the scope of their project, start without a framework, and the complexity reaches a point where the framework would actually help.

I'm not sure what that looks like, because if it gets complex enough it's a sign I need to refactor, imo.

I once built a project-tailored combobox using Alpine.js - this is about where it breaks down.

It worked, it was a lot of fun to write because it went really fast, even with some bells and whistles. Whole thing was my escape hatch when datalist attribute didn't work. It also worked well.

Alpine JS feels like a simpler version of Vue 2 without a build step and without any of the complex or confusing stuff (and of course with a focus on HTML not rendered by JS).

But when I saw what this turned into as a BE colleague copied it to the next form, making some adjustments... oh my, I prefer external and reusable JS (or a JS-first approach to templating, like React) any day.

Still, Alpine is really awesome for minimal interactions and simple JS.

When working outside React, it's hard not to miss it for the simplicity of doing everyday stuff inline in the HTML.

Alpine is primarily designed to be reused via server templating. You use a single template per component to do the in-HTML side, using the server template's facilities to handle variations as necessary. Then you can factor out complex common behaviors into Javascript using Alpine.data.

It definitely does have a maximum size of project it's suitable for. In particular, it's thoroughly individual-component-based; changing anything outside the component requires tacking on non-native hacks, and doing a full interactive app with it would be a painful exercise. But for adding simple interactivity to a primarily server-rendered web page, I've found it to be quite useful.

Should have mentioned that I made a generic Blade component from it (it was a Laravel project)

Copying still happened, take that as you will - in this case that was the problem :) Might be my implementation was not generic enough, but tbh the colleague was not especially proficient at JS. We had a productive conversation about this, but this particular project ultimately was lost by my former employer. The reason was not this autocomplete component though :)

It might be easier to staff for. But developing a React frontend takes way more time than just server rendering HTML and layering in JS for the vast majority of use cases.
that's just speculation. I can say also anecdotally from my experience, developing a react frontend takes way less time.
I'm speaking from experience on a pretty wide variety of commercial web projects. Been building websites for twenty years. Frankly, it's not even a close competition. What I've found is that a lot of teams don't even track their time, so it's likely many developers don't realize how large the React penalty is. I would encourage devs to spike on both approaches and do a thorough accounting of their time.
>But you're already using it for the rest of your site

I'm not

Also with "onlick" you have to lick it to trigger the event.
I see you are also a fan of lickable.js
What are HNs policies around tongue-in-cheek comments?
Tongue-in-cheek is OK after a lick.
I can't tell if this is an actual pseudo-complaint about a joking comment, or an honestly pretty amazing pun on licking/tongue.
I thought the point of the article was more to avoid react if all you want to do is change background color. Thus more: don't use react in the first place, rather than: here is how to use less react.
Does anyone have a good list of vanilla approaches? I'm a fan of details/summary, but I'm sure there are more I don't know.
Tbf they got better. Jquery basically existed because the js builtins were hairy
I like datalist quite a bit for „poor man‘s autocomplete“ - you can dynamically fill it via JS and will get the suggestions shown in the completion fields above the keyboard on mobile and… well, something (?) on desktop. Not as nice as an autocomplete, but with way less issues re accessibility etc.

Edit: Forgot two things:

- You can disable the `fieldset` attribute to disable all inputs within. So properly nest your forms and you‘ll have a simpler way of controlling forms.

- Buttons can have a `value` attribute which works great to differentiate between various action paths for e.g. list items (delete, edit,…)

I'm a big fan of that approach, but it's kind of funny (and sad) that such a simple page doesn't even look as intended with JavaScript disabled, as there are some placeholders of CloudFlare's Email Address Obfuscation visiable in some of the code listings.
I love that people are finally coming around to abandoning the build step.
React was designed to solve all these problems. Now these problems are used to solve react.

Programming, like life, is a flat circle.

No, it was designed to address problems that were not solvable by the then-current state of simple technologies.
All the things React does is doable with plain javascript. There aren't any extra features added.

React was designed to address complexities. It is an abstraction.

Now we want to go backwards. Getting rid of the abstraction to get rid of complexities. But getting rid of complexities was the whole point of react.

Agree to disagree. Building a React frontend is extremely complicated compared to server rendering HTML with progressive enhancement. It introduces state management to the frontend for even the most basic tasks, which is not something most web applications benefit from. When I built my CI/CD platform (Beaker Studio), the React portion probably added a solid 50% extra time to the project and really did nothing for it functionally.
No you agree. You're just not understanding.

The purpose of react was to simplify the complexities of front end web development. Just like the purpose of the DOM was to do the same thing.

Now this article is pointing to going back to the DOM for a similar purpose. The cycle on the great circle of life occurs because we are repeatedly attempting and failing to fulfill the singular purpose of building a clean API for ui construction.

The dom was a failure, react was a failure. What do you think going back to the DOM will do?

> The dom was a failure, react was a failure. What do you think going back to the DOM will do?

It'll give me that extra 50% effort back. Although I've used React for years, I have never been on the bandwagon. Having built many React SPAs with different teams at this point I'm confident it has always been a step backwards.

Yeah but react was designed to address a problem. I don't know if you recall but people were complaining a lot back then. There were tons of frameworks attempting to solve the issue. Only react came out in top.

By stepping back we are just going back to the same problem.

The next abstraction will attempt to solve the same problem again. Very likely in a similar way react failed, the next abstraction will introduce new issues and there will be another trend to go backwards again.

I don't have fond memories of early React; It was extremely verbose not having hooks until relatively recently, build tools were necessary but a horrible mess, and it was falsely advertised as being faster than vanilla JS. Hype around Facebook carried React. It has improved massively since then, but so has vanilla JS. I don't see a transition away from React as a step back at all. React made rendering new elements client-side and attaching events cleaner, but that was never a hard problem per se and we have web components now.
I never said a transition back from react is not an improvement. Again you're not getting it.

I'm saying we had problems with vanilla js initially and we've never moved forward. The fact that we are going back to vanilla js is reopening all the old issues are a sign that we are in stagnation.

Nothing has changed. It's a circle of attempting to improve and failing.

I dunno man, I don't consider browser APIs to be a failure. In fact, it's probably the most popular UI toolkit in existence by a wide margin. It being a collection of evolving standards doesn't count against it in my book.
Many bad things are popular. Java, C++, JavaScript. Popularity doesn't preclude something from being shit.

The front end UI isn't a collection of evolving standards. It's the same standard with more and more cruft added on top.

HTML wasn't designed for what we are doing with it now. Each additional layer... css, JavaScript, the dom, typescript, react, is a new layer over an old thing. It's like never buying a new car just modifying your old one from the 50s to stay up to date. That's why the entire front end API feels so bad. It feels disorganized with complexity that exceeds necessity.

The complexity of the spec even took years for browsers to get right. This is not a sign of good design. It's a sign of endless designs layered on top of each other all in vain effort to modernize everything and keep it backwards compatible.

There's a difference between being popular, and being the most popular thing in a category ever and keeping that title for decades with no serious challengers. The browser as we know it with the DOM is the latter. Maybe that will change with new APIs that hook into the canvas, but we're still a ways off from that and I suspect the DOM will remain in the picture even then.
C++ also has had that category for decades. Longer than browsers. Rust is challenging that hold right now but it's far from winning.

You're right the dom will remain in the picture for a long time. Doesn't change the fact that it's horribly designed.

> The dom was a failure, react was a failure. What do you think going back to the DOM will do?

Facebook (rightly) said the VDOM was needed at because of rough edges around the performance of DOM implementations in assorted browsers. The DOM has improved over the past 15 years or so to the point where things like HTMX and AlpineJs are viable for more use cases. React and the DOM have not failed, they are tools that have their uses and limitations. Looking for one solution to rule them all is ultimately an exercise in futility and disappointment. Instead we should be looking at ways to integrate React and hypermedia so they interoperate more smoothly (e.g., web components or similar solutions).

No. The entire front end ecosystem is simply cruft added onto something that was fundamentally designed for something else. The "improvements" are attempts at fixing a flawed design while maintaining the old core design Similar to the cruft on top of C++.

>Looking for one solution to rule them all is ultimately an exercise in futility and disappointment

React and the dom were also exercises in futility and disappointment. They didn't seem that way at the time but as time went on it became clear what their problems were. The same thing can be said of htmx and alpine and whatever big framework that comes next.

Additionally who says their can't be one solution to rule them all? You think if your quotation eludes to some fictional story of lotr suddenly it makes sense? There is nothing in reality or logic that says we can create a design that can do better than all the apis that currently exist.

This idea that you can only male tools that do one thing well is fundamentally illogical. There are tons and tons of tools that do multiple things well. Take your car. It doesn't just get you from point a to point b. It air conditions you, it plays music... It provides safety, it gives you directions.

I think this is because HTML, CSS, vanilla JS, browser DOM implementations, and networks have all gotten better. Whereas the complexity/churn around JS tooling (and to a lesser extent React) has grown. Additionally, the overuse and abuse of React, to the point people are making largely static sites with React, which is largely a total waste of time. This has caused people to take a second look at their options, which should be viewed as totally natural.

I don't think of it as "going backwards", so much as reassessing and questioning the tools we are using and using the best one at hand. I don't know of anyone who suggests using hypermedia for all applications, just use it where appropriate and use React when simpler technology falls short.

How was React designed to "avoid the build step" or "make View Source useful"?
React was designed as an abstraction layer on top of the source. Why?

Because the source was too complex.

Now we want to expose the source and get rid of the abstraction... Why?

Because the abstraction is too complex.

Recurse and repeat.

There won't be a repeat. WASM is a clearly better compilation target than JS, and browsers have greatly improved the "vanilla" DX.

TypeScript ecosystem is the Enterprise Java of this decade, except it's built on shakier foundations, i.e. you can run some ancient JVM, but good luck relying on an ancient browser version & node dependencies. There will probably still be tons of job-security in the next couple decades, but it's not forward-looking technologically.

Building a language and a framework on top of wasm is just another abstraction.

Ironically you mention the jvm which further proves the existence of the flat circle.

We've done it before... We will do it again.

Yes, I remember when Microsoft FrontPage was the go to wysiwyg editor for web development along with Dreamweaver most styles were added inline.

At some point wysiwyg editors fell out of favor as they generated both unmaintainable styles and markup.

Style sheets took hold and the insanity that was inline styles were dropped in favor of external style sheets.

Today we have tailwinds.css and inline styles are coming back in vogue.

Wysiwyg editors are coming back in the form of code generators that convert designs into react components.

This author is even a proponent of inline event handlers which were the standard way of doing things before JavaScript really became a powerful language and added "addEventlistener".

Flat circle repeated over and over again.

Part of me wonders if these authors are just too young to remember those days. Otherwise why wouldn't they mention the historical context when writing these kind of articles?

It's funny when younger people espouse these new ideas as new and revolutionary when really they are a return to older patterns that fell out of style for whatever reason and are now being resold with different packaging.

There's no theory behind program design and organization. We have no formal definition about whether one design is better than the other.

Thus, History is doomed to repeat itself as software technology moves horizontally forever, with practitioners never knowing if the current abstraction was better than the previous one.

How poignant - another post on the front page - https://news.ycombinator.com/item?id=38236607

Top quote in the article

> I don't think computing is a real field. It acts like a pop culture, it deals in fads, and it doesn't even know its own roots. And worse than that it does not know about the really good things that were done in the past. — Alan Kay

Really good quote. Pretty much sums up computing. Here's the thing, everyone doesn't realize it's just a bunch of fads. People think of it as some sort of science where we're just continuously improving and getting better.
This is a blog spam post written by an author that has no credibility in the space rather than creating an agency that touts itself as "A software agency that doesn't suck.". How bizarre.

Even more, the author uses every possible library under the sun, from Tailwind to Framer, only to evangelise about raw HTML and topics he provides no credibility on.

To add to that, even the links to learn more about their agency all lead to Twitter, rather than LinkedIn, Clutch and Sortlist.

I like how he concludes "The practices and principles described on this site are still considered niche in the industry as a whole". Like he's the only one out there who knows about the details/summary tags, or who uses static HTML documents instead of React.
The details tag is a mainstay of the "You don't need JS" genre. Every time I see it mentioned in one of these, it's always presented like it's new, unknown, and maybe a bit secretive. "OoOOoOo, bet you would write a component for this right? Well aren't you feeling silly??"

I think it's showed up on every app I've worked on for the past 5 years.

Are the practices that the author wrote about common? Judging from comments, frameworks are more common than plain JS, and half of those using frameworks don't fully understand what's possible without one.

I think it's fair to say a practice is niche if you don't see it anywhere and appear to be one of the few talking about it.

Let's see your website.

(comment deleted)
Textbook ad-hominem mixed with a side order of appeal to authority.
Yeah, kinda gross. It takes zero effort to call someone's writings "blogspam". Would love to see comment OP's website so we can compare it to some random "agency".

Probably some "entrepreneur" chud.

This one confuses me:

> Where libraries are necessary, use libraries that leverage html attributes over libraries built around javascript or custom syntax

And then they demo using _hyperscript [0] as encouraged. However, that's a library built around a custom syntax. It's only using an HTML attribute to encode a script that's in a new language you need to learn. Is this serious?

[0] https://hyperscript.org

Alpine.js would have been a better recommendation according to the authors advice as it is straight forward JS plus HTML attributes.
I think hyperscript has some people trying to hype it up bc it’s related to HTMX, but imo is more of a fun novelty.
I would agree - the example of an an attribute of `_` and then some obscure DSL statement as a value looks super weird and confusing.

I would rather there was just an explicit `onclick` (or some other event) in there with a vanilla JavaScript statement so I know what is happening.

Maybe the author swapped the encouraged and discouraged.
yeah, kinda.

source: I'm the creator of hyperscript.

I'm not saying hyperscript isn't serious (I have no opinion on it at all actually). I'm saying the claim "avoid DSLs" followed by an example using a DSL is a sign of unseriousness on the part of the author of HTML First.

Six principles and one of them is presented with an example that blatantly violates that same principle. I could see a mistake like this slipping through if there were many more principles and examples, but this is a relatively short piece for such an error to slip in.

Perfect. This place is overdue for an exhaustive debate about HATEOAS/REST/etc, and you have an incomparable talent for starting such a debate.
I suspect this is a 'List of tips' written explicitly to promote hyperscript.

Its example is also pretty weak. Vanilla solutions (Tip 1) works just as well:

<div> <input type="text" oninput="this.nextElementSibling.innerText = this.value"/> <div id="output"></div> </div>

note that the <input> tag does not use and does not need a closing slash and never has in any HTML specification.

https://html.spec.whatwg.org/dev/embedded-content.html#the-i...

Yep. It’s one of a handful of void elements along with <img> and <br>.

Also using a slash to self close a tag is not part of the html spec and it never has been part of the spec. The browser doesn’t know what that means on any tag. If you write <div /> the browser ignores the slash and thinks you still haven’t closed your Div.

I'm adding context to this because you're only telling part of the story:

self-closing tags are necessary for void elements in XML and XHTML, both technologies that are still supported on the Web. Since XHTML processes HTML as XML, it forces it to be well-formed. Unlike HTML, which has all sorts of tag-soup and quirks modes and other things, because it's lax in its syntax.

Void elements lacking the need for a closing tag or closing slash is one of the weird edge cases in HTML. While it's not in the HTML spec, it may still be seen in the wild in XML and XHTML documents and is not universally bad or unsupported.

You can view HTML as a weird, quirky version of XHTML if you want. But XHTML lost the war. Browsers are HTML5 engines, not XHTML engines.

And if you're writing HTML, the browser considers <br/> to just be a weird way to write <br>. The slash is non-significant. So confusingly <script /> is not equivalent to <script></script>.

The problem I have with self-closing tags is that I've met so many web developers throughout my career who think that browsers understand self closing tags. I used to be one of them! And that will almost always, but not always work out fine:

- React / JSX supports self closing tags. So do a lot of other web frameworks.

- Void elements ignore the /. (And you don't need to close void tags anyway). So you can write input, img, br, etc tags however you want.

- HTML5 will auto-insert missing closing tags when it needs them. Eg, <div><span /></div> will render as you expect because the browser will automatically close the span when you close the div. (!)

But it'll confuse you in weird ways. Like <script src="..." /> - which the browser dangerously interprets as an open script tag. Subsequent text is interpreted as javascript!

I think its good practice to be clear in all source files whether you're writing XHTML (eg in .jsx) or writing real, god fearing HTML. And then never use self closing tags in HTML. Sooner or later, someone will think they matter and you'll get bugs.

I can't disagree with making sure you're using them when they matter and avoiding them when they don't.

There was no real 'war', XHTML 5 is still a thing. Browsers are HTML engines because people who write HTML don't want to be forced into well-formed markup. They want the browser to guess what they meant and run with it.

There's also the whole "we need to be compatible with almost every HTML file dating back to the early 90s" conundrum that makes clean breaks in behavior, like XHTML, hard to pull off without pissing people off.

It should be clear which one is writing based on the DOCTYPE element. IIRC XHTML still requires a DTD to ensure its schema can be validated, while HTML 5 did away with it altogether and now just uses <!DOCTYPE html>

> There was no real 'war'

There was definitely a debate over how web browsers should interpret web pages - as XHTML or "quirks mode". HTML5 (with infinite backwards compatibility) was the outcome. Every major web browser implements HTML5 - complete with its super quirky and complex, but fully specified and consistent parsing rules.

> XHTML 5 is still a thing.

Is it though? On the web? I just tried, with this html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html><body>
      <div>
        <div style="background-color: hotpink;" />
        yo
      </div>
    </body></html>
Q: What do you expect the background-color of "yo" to be?

If this was an XHTML page, tags should be able to self-close. And in that case it should be black on white. But try it. Its not. The browser ignores the self-closing part of the tag, so "yo" is inside the inner div and it shows up in hot-pink. The outer div is then not closed correctly. (2 divs open, 1 div closes). If the page were processed as strict XHTML we'd also expect a warning or error, but the browser doesn't care. Neither firefox nor chrome emitted anything in the console about any of this.

As far as I can tell, the XHTML doctype has no effect here. The page is interpreted - as all webpages are - by the browser using HTML5's parsing rules. Not XHTML's.

There are contexts in which XHTML still exists. Like JSX. But the browser is not an XHTML renderer. Rail against HTML5 if you want, but people need to stop pretending that the browser supports self closing tags. They are not part of HTML5. Pretending they are causes bugs.

You need to serve it with the right mime time (application/xhtml+xml) or in case of local files use .xhtml extension. Then it's processed as XHTML and rendered as expected.

Also you need namespace declaration otherwise it will be rendered as unstyled xml.

This is all part of HTML5 spec: https://html.spec.whatwg.org/#the-xhtml-syntax

I'm going to let this link to a simple XHTML document speak for itself. I've configured it to work on lighttpd via the `mime-types.conf` file, and even have a commented-out meta tag you can use to fake it in cases where you can't manipulate a server.

https://zlg.space/misc/example.xhtml

Let me know how your browser sees it.

(comment deleted)
XHTML may not be mainstream with people authoring web pages, but it is a thing within publishing pipelines that generate XHTML from other XML-based sources like JATS or DocBook. It's also a thing at least in ePub 1 and 2 content (I can't recall if they relaxed it to HTML for ePub 3 or later).
> Eg, <div><span /></div> will render as you expect because the browser will automatically close the span when you close the div. (!)

span is a bad example. indeed it will close - but then it will reopen (!) when the next text node occurs. <p> is a better example, and it will also auto close when you try opening a new <p>, which can be rather convenient when trying to write concise html.

> Void elements lacking the need for a closing tag or closing slash is one of the weird edge cases in HTML. While it's not in the HTML spec

It's explicitly in the HTML5 spec as allowed, but not required.

Which makes the example even more egregious. There are certainly better ones that:

1. Can't be easily done with vanilla JS and so can justify using a library.

2. Don't need a library with a DSL in direct opposition to the claimed principle (avoid DSLs).

Yeah I stopped reading as soon as I saw this one.
I love the ideas here, but honestly the examples are a bit weak here.

> Where possible, default to defining style and behaviour with inline HTML attributes

but their example wouldn't work.

  <div class="bg-green" onlick="this.classList.add('green')">
should probably be

  <div onclick="this.classList.add('bg-green')">
which I think makes it a little more clear how weird this could get if you wanted to add more styles. You just keep growing the params passed to the ClassList add method, in a string. I would personally find

  <button></button>
  button:active { background: green; }
to be much more readable, but the author seems to imply this is complicated due to their approach of "Locality of Behaviour".

--

> Where libraries are necessary, use libraries that leverage html attributes over libraries built around javascript or custom syntax

I totally agree! But why is your example of a library not built around javascript or a custom syntax feature:

  <input type="text" _="on input put me into #output">
  <div id="output"></div>
That "on input put me into #output" I think is more jarring that the library shown as the bad example. Even better, this could just be some JS, without a framework at all.

--

> Prefer "naked" HTML to obfuscation layers that compile down to HTML

Their example is to not use Rails ERB tag helpers, in your templates. I don't think this is that big of an issue, these helpers can actually handle a lot of things that will look messy if you use the minimal amount of templating to write them. The example leaves off unique dom ids, turbo tags (very HTML/no JS focused!) and iteration.

>> Where possible, default to defining style and behaviour with inline HTML attributes

This was my critiquing point as well. Style configurations should be separate from actions, with only references linking the two. It's the only way that makes sense for anything meaningful.

Yes, I could technically write a python app where all SQL database connections have hardcoded SQL as one one long file, but that is poor practice. This suggested principle seems the same to me.

Can the people that want this HTML-first world style it to look the ways they want themselves?

My experience has been that proponents of HTMX and the like skew heavily backend and never feel comfortable with CSS.

Why listen to UX thoughts from a population who are scared of UX?

This strikes me as a cynical take. Having floated between backend and frontend a lot, frontends naturally tend to become very complex; even before the web. And with three different Turning complete stacks (HTML+JS+CSS) the web already feels pretty heavy before adding in another stateful framework and build tooling to support them.

Folks can disagree about how to keep the system simple when looking at it from different points of view. All those opinions are worthy of consideration.

JS frameworks seem inevitable. Any time I've worked with native JS in a reasonable size projects, it becomes necessary to create libraries and common conventions, that starts to look like something approaching a small framework. A framework is just common patterns for solving problems. I think what a lot of developers object to is the stack of build tools required to transpile, bundle and link code together when using these frameworks, in addition to the complexity that comes with dependency management, rather than the use of the framework themselves.
Having worked with it for 20+ years I've just been left convinced that the biggest mistake frontend dev has made in that time is to pretend that CSS is a language that should be 'engineered' instead of a design flavour that should be build up / torn down lightly on demand. It's esoteric corners should have been fixed and simplified so designers could learn and explore design through markup as needed, rather than double-downed on to where we are now.
I am very happily listening to UX thoughts from people who specialize in UX.

What I am decidedly NOT happy with, is the frontend using as much, or even more, internal logic, magic, and build steps as the actual business logic.

To put this another way: I will happily listen to an interior designer on his thoughts about the color of the drapes. But if he tells me that this color means he has to bring his own crew of stonemasons, carpenters, and electricians, because somehow that color requires massive changes to the architecture and power lines of the house, I am going to grab a piece of cloth that vaguely has the color I want, and make the drapes myself.

That applies to backends equally, but you don’t get thinkpieces on how that makes it a great idea for frontend devs to avoid all those silly DTOs and design patterns that complicate the server code.
You do though. Hating on the cloud is pretty popular as well.

But in the end, because of nature of things, slugish frontend has bigger affect on user's experience then slugish backend.

It applies to everything, everywhere.

Overly complicated, architecture-astronaut code, that leans on frameworks for no good reason, is bad, no matter what part of the stack. And yes, this is true for the backend as well. There are people who will happily import 3 different frameworks to make a POST request in Go.

I’m not able to make a page look nice (or even decent) without a CSS framework. But I think I’m at least OK at understanding how to make the interactions and workflows follow the “Principle of Least Astonishment”.

In other words, I’m not scared of UX in general, just not confident in my current abilities in UI (which is just one aspect of UX).

Here to bust your assumptions. I skew backend but love CSS, and am one of the better UX engineers I know of. I also dislike javascript a lot, and find that the htmx approach cuts a significant amount of complexity out of your app (e.g. your views can talk directly to your daos.)
I’ve met enough people that aren’t like you that your lived experience, real as it may be, doesn’t really change my opinion much.

For every one of you who isn’t scared of CSS there are like 40 people into HTMX that make bad UXs even by the standards of internal company tooling.

Similarly for every React/$oftheday dev who creates a snappy, race condition free, spinner free, app that feels almost as snappy as the web prior to React/$oftheday, there are 40 who create sluggish, unmaintainable tyre fires.
What literature exists on UI and UX that isn't condescending or clueless in tone?

Interfaces are as unique as humans are. There's a reason we have emacs, vim, and Notepad.

Refactoring UI fits those constraints. While it's by the creators of tailwind, it doesn't make assumptions about the css you use to achieve your desired UI.

https://www.refactoringui.com/

Thanks for giving me something interesting to consider! This looks like an earnest product that could help me at least understand where others are coming from on design, and could probably add flavor to my own UI focus (gamedev).

I don't often have a positive reaction to something like this, will definitely revisit it when I have the spare cash.

To be fair, most UX "experts" are too busy chasing interfaces that are "inclusive", i.e. built for toddlers.

Show me a powerful program with a "good" UI by modern standards and I'll show you a mess. VS Code is a prime example.

Interesting example. Why would you say VSCode is a mess? I feel like it's not in line with the current UX Zeitgeist I assume you're referring to (touch-first, wasteful whitespace, manipulative patterns, reduced functionality) at all. It provides multiple layers of access to functionality that allow the user to choose their trade-off between discoverability and speed. The UI is compact with very little padding and shows a lot of information at once. No affordances to touch input are made either.

Another powerful tool that is built on modern UX principles would be Fusion 360. In my experience, it makes me as a user much more powerful and actually provides more functionality in a more productive manner than its competitors and predecessor. Would be interested in you explaining how that UI is a mess as well.

VS Code is a mess because there are few places I can click in the UI without triggering some weird part of the UI. Almost the entirety of the bottom bar is reactive. The sidebar has too many views to keep straight, it has an extension store or something? Using VS Code feels like handling a tool with no handle. I'm sure it has something useful but I feel overwhelmed and constrained when I use it. I can't depend on any of my prior UI exposure to effectively navigate VS Code without taking my head out of the code. It's simply too much on screen at once and relies on visual iconography which will NOT result in the same ideas conveyed between different users. VS Code feels like it's meant primarily for the enterprise, on projects that are massive and have extensive SOPs. I tried to adapt some of my development to it, just to try it, and bounced off really hard.

I'm really just more at home in Vim and a terminal window off to the side. Microsoft's way of doing things has never really clicked.

I can't speak for Fusion360 because I don't know what it is nor have I used it. There's just an issue in UIs these days where they're either toy-themed (Twitch, Discord, Etcher, other "friendly" software) or so overwhelming that you don't know where to start.

Where is the QuickStart guide for VS Code, for developers? With MS in particular, they do a poor job of reaching out to developers and actually understanding how they work or what they like. Maybe they only serve a particular type of developer; an audience that I'm simply not part of.

I find the silence that accompanies the negative score above to be rather damning of this community. I was asked why I felt the way I did, and I explained it. If you have a problem or disagree, show it in the comments.
Visual iconography doesn't need to transmit the same ideas to different users, it's there to reduce space taken but still be identifiable to an experienced user of the tool.
I love the idea!

In my current company we started with HTML and embedded JavaScript at the bottom and Styles at the top. Everything in one file, very easy to find and understand.

It was "a little bit" slower. Pagespeed Insights didn't like it.

Now we are "modern" with CSS and JS in a build process. And nobody knows which file to look at...

My new Projects will start with HTML first, again.

My credibility: 45 years, commercial web programming >25 years, 3 successful web companies founded as CTO

Well. This was how we did web development before it turned into so many abstractions that most comments either is too young to know or simply not understanding that adding more abstraction is not ideal.

People here say "show me this on a big project" well how about they showed us how the thing they are doing on a big project has turned out.

The cleanliness of HTML and CSS is astonishing. That's a quality mark in my view. If you to move away from that you miss out on certain aspects imo.

Assuming your site doesn't literally have only a single page, how do you handle reuse of styles and potentially behavior across pages if you put everything into one HTML? I've tried out the "everything in one file" approach in various contexts where it has worked out fine, but a website seems like the one place where it would quickly become an issue. I would at the very least assume two reusable kept separately from the .html(s): .js and .css.
You're absolutely right. We had additionally one common JS/CSS file each.

Every approach has its pros and cons.

This is all nice and suckless, until you will have to scale your codebase and/or add some more features (possibly alter someone's code) and deal with exponential complexity of DOM manipulation. React came to solve all this
While I agree with most of the arguments here, this article feels a little contradictory - it recommends Tailwind but also tells us to 'stay clear of build steps'. Shipping massive CSS/JS resources goes against the whole inclusivity principle - many people don't have super fast internet connections or powerful enough computers..
I don't use Tailwind anymore at the moment, but in my experience, it does not lead to shipping massive CSS/JS resources. In fact I don't know about any client-side JS at all that is emitted by Tailwind (my last experience was 2.x, not sure if anything has changed).

Regarding the CSS size, my experience was the opposite, Tailwind output was usually a lot smaller than hand-written CSS.

I have nothing against plain CSS either though; but it's at least as easy to make a mess.

I think what the OP meant is: Tailwind requires a build step to extract use classes. Otherwise you need to ship all of it.
It's true that it requires a build step, since tw 2, AFAIK there's not even a way anymore to ship "all of it". CSS rules are generated on-demand for the classes that match tailwinds syntax.
I think GP is talking about how, without the tailwind build step, you ship all of tailwind, which is unquestionably a lot of CSS that you aren't using.

Maybe if you use a CDN, so hopefully the user might have a local cache of it from somewhere else, that can be avoided?

Still though, tailwind is pitched WITH it's build step normally, making the author's point about avoiding a build step a bit odd.

This was only the case in Tailwind 1 and heavily discouraged by the documentation, except for development.

Tailwind requires a build step and shipping the 1.x development build was explicitly not meant for production.

Trying to use tw 1 like this without a build step, you can't even define a custom color scheme.

If this is what you want, I'd use a library that actually supports this. Maybe tachyons? But tbh, without the build step I'd consider using Tailwind at all a massive mistake. Then I'd prefer handwritten CSS.

Custom properties should make sth like this a lot more viable though. I'm sure there are libraries that better fit this use case, if you want to use a CSS library.

> Maybe if you use a CDN, so hopefully the user might have a local cache of it from somewhere else, that can be avoided?

Browsers partition caches by origin now for privacy reasons, so this is no longer possible. If the user doesn’t have it cached from your website, they don’t have it cached.

Did your experience involve the (recommended) build step? It uses, at least last I checked, a purgeCSS step to remove unused rules and decrease the css size.
This changed in tw 2, everything is generated on demand, PurgeCSS is no longer used.
Tailwind has a standalone CLI which can be used for the build step. I do sort of agree that it's a bit of an odd recommendation in the context of this article, but the build step can be extremely minimalistic, and another nice thing is that the results are still inspectable CSS.

I use tailwind on my personal site, which is otherwise entirely just vanilla HTML, and it doesn't feel very intrusive to run the CLI in watch mode when I'm writing styles.

The only thing a build step changes about CSS/JS resources of this kind, is a minimization of the libs...which is entirely achievable without building, by simply including the already-minimized version.

I think what the article is about when it says to steer clear of builds, is complex builds, where transpilations and similar changes in format have to happen, in order for the page to work.

> The only thing a build step changes about CSS/JS resources of this kind, is a minimization of the libs...which is entirely achievable without building, by simply including the already-minimized version.

This isn't true, though—Tailwind's build step isn't just stripping out white space, it removes unused selectirs, too, which can't be done in advance.

I made an atomic CSS library that doesn't need a build step, if anyone wants one (spoiler, nobody does): https://casscss.github.io/cass/
Imho, bullet points on the border box seems weird to me (https://ibb.co/d0sDsQ2).
Thanks for the note! The left padding and margin situation on the ul is the bane of my existence.
Copy what other more popular frameworks are doing :P

I haven't looked at your css, but maybe changing the box model could help?

The OP was making a point that the build step should not be required to run/display a web app.

For example, tailwind without a build step is just the entire library. This means one can go a long way and even have a functioning web application without introducing a build step.

I would say stripping unused CSS is in the same context as optimizing images, fonts etc perhaps generally a "cleanup & prepare assets for production" step.

I read it the same way, yes. Good point with the cleanup: - it’s one thing to need to run build for it to work; - it’s another thing to run build to make it smaller;
Tailwind doesn't exist without a build step (at least since v2) — the whole point of Tailwind is that it is a build tool, an alternative syntax for writing CSS.

There's a kind of development version where that build step runs in the browser on page load, but it's still a build step in the sense of generating all that CSS dynamically, and it will produce a poor experience for a user if you try and use it in production.

Deno Fresh uses Twind, which avoids the build step: https://twind.dev/

But IIRC it doesn't offer quite everything full Tailwind does. In general I was frustrated with Fresh for not being up-front about the fact that it is largely built on Preact and Twind, and you must buy into those libraries first.

Article doesn't even have anchor tags
The person who created that website should have a look at the recent Rails updates :-)

Or check out DHH's most recent thoughts on minification etc.

Maybe I’ve already drunk the koolaid, but if I end up building a new app from scratch, I would really like to experiment with something similar to what the author describes:

Django for most (if not all) of the server-side code, Django templates generating HTML, htmx handling most interactivity with html attributes and, when necessary, hyperscript (for use cases that can’t be covered easily by htmx). I would probably stick with downloading minified Bootstrap for styling (Tailwind requires a build step, and I don’t think I have done well in the past when I waded into “class soup”).

Has anyone here tried something along these lines for a non-trivial app? How is it going?

I have used this approach for internal tools and it has been great. It makes it much easier for one person to build the whole app, frontend and backend, and makes ongoing maintenance much easier.

I am working on https://github.com/claceio/clace which takes this no build approach and makes it easy to build portable applications, using Starlark running in go to configure the backend.

I used this exact approach: Django backend, Django templates and htmx. It has been a delight.
This is what I’ve used for my last couple of projects, including https://www.semiform.ai - not sure I’d call it “non-trivial”.

I’ve really enjoyed this stack. The structure just seems to click in my head better.

I think you might find that relevant. (But in short, the author expressed being verry happy with switching to 'stack' you described) https://youtu.be/3GObi93tjZI
It is so much easier and faster to build web apps using TypeScript, Vite and React (or any other similar stack) rather than vanilla JS. I find this “leveraging the extreme simplicity” effort wholly misguided.

It’s neither “enjoyable” nor “seamless” to manually synchronise the backend, the frontend logic and the DOM of your app without frameworks.

And maybe the trite talking point of helping young developers by sending unoptimized unminimized comment-rich source code directly to end-users held at least some weight in the 00s; nowadays we have an abundance of tutorials, courses, conference talks and open source projects that can help autodidacts to learn anything related to web development.

It depends, I think.

For “apps” vanilla js isn’t enough.

But for a blog with some animations or simple validation, things like next or gatsby is WAY too much

My rule of thumb is that if you're building something sophisticated enough that you want to reach for more "advanced" js frameworks then you shouldn't be building it as a webapp.
Why?

The web has moved far beyond a document sharing platform. It’s the largest, easiest (for users,) and most compatible software development and publishing platform ever. By far.

It’s not good for everything all the time, but it is good for most UI focused software most of the time.

Is there no appreciation for using the right tool for the job?

When you build an app on Electron, you're forcing the client to run another browser, alongside whatever other browsers they're running. Due to the complexity of the Web, running a browser now takes hundreds of megabytes of RAM, sometimes a gig or two. Now imagine you have 8 different Electron apps you use. You have the system resource use of 8 separate browsers now. Congrats.

Secondly, there's no integration between Web apps and the OS. Only recently did things like light and dark mode get OS-level support, so there's that much, but long story short, Web apps don't integrate well with the system. They tend to be shipped in containers, too, so while it may be "good security" it results in a worse runtime environment and uses more resources.

The Web is a document platform, first and foremost. The building of V8 and Node.js, the myriad frameworks, etc, are the result of companies trying to turn an existing protocol into a moneymaker. Tim Berners Lee never intended the Web to be an application platform or a vector for DRM. For-profit interests created all of that extra complexity, and took over standards committees to push their ideas through.

Web apps work best when they take advantage of some of the Web's strengths. If your program needs to talk on the network a lot and it's already working with HTML, then yes maybe it should be a webapp.

The problem is everyone's ignoring the complexity, resource use, and tangled knot of abstraction on the client's end. It's "not a big deal", until it is, then we'll go back to rediscovering how easy native development is with a smart enough Makefile. All the major UI toolkits are cross-platform, there's little excuse.

I think you are totally correct- we should we building them as electron apps instead :)
(comment deleted)
I agree in principle that HTML is the best option for a good user-experience, but it quickly breaks down in terms of developer-experience and maintainability. However, we don't need to compromise on either by using a solution like Qwik[1]. Where the page progressively becomes more interactive with JavaScript, and doing as much work as possible on the server beforehand.

1. https://qwik.builder.io/

> nowadays we have an abundance of tutorials, courses, conference talks and open source projects that can help autodidacts to learn anything related to web development.

That method was horrible, as someone who struggled with poor knowledge sources until HTMLDog and MDN became a thing.

...Conference talks? lmao your class is showing, the average self-taught hacker can't afford to go to those. Anyway, View Source is a good way to learn how to do something you see for the first time. It's a necessary feature to double-check what's being sent to the browser when you're developing, too, and keeps website operators honest by giving you a way to inspect how they build their site.

Personally I think webapps are the wrong solution for a ton of problems, but the industry won't accept that until the bottom line is affected. I'm waiting for native apps that communicate over the same commercialized protocol. QUIC but its own piece of software instead of co-opting the Web.

> That method was horrible, as someone who struggled with poor knowledge sources until HTMLDog and MDN became a thing.

But they are a thing now.

> ...Conference talks? lmao your class is showing, the average self-taught hacker can't afford to go to those.

An average self-taught hacker can afford YouTube. That’s why I explicitly mentioned talks and not conferences per se.

> Anyway, View Source is a good way to learn how to do something you see for the first time. It's a necessary feature to double-check what's being sent to the browser when you're developing, too, and keeps website operators honest by giving you a way to inspect how they build their site.

Opening up source code is a choice. And if a creator wants to open-source their app, I would rather look at it in GitLab rather than in production.

> Where possible, default to defining style and behaviour with inline HTML attributes

Wow, have we just come full circle after 25 years?

I literally--literally, not figuratively--facepalmed when I read this.
This comment or that part in the link?
The advice to put inline styles in your HTML.
(comment deleted)
And it isn't even done in the example.

>class="bg-green"

These tailwinders are everywhere these days.
(comment deleted)
(comment deleted)
I love this. Could you please consider changing the example from a clickable div – which is an accessibility nightmare – to a button?
Why is a clickable div an accessibility nightmare when the button element has a lot of browser-preset styles that are harder to override? Assuming you put all the relevant state styles into place like :hover and :active and whatnot, what's the problem? Button elements are best used in a form. If you aren't submitting a form, what's the button there for?
button { all: unset; }

This removes all the preset browser css styles. An accessible,styled <button> is much easier to achieve than an accessible, styled <div>

What makes it more accessible?

I suspect the answer is that screenreaders don't look for all clickable elements and are naively focusing only on buttons.

That’s exactly it. With native buttons and links you get all the accessibility for free. If you attach events to non-interactive elements, you have to do all the accessibility work yourself. In a custom interface, a button outside a form is perfectly valid and the best choice for the above reason.
Yeah, no. If the only reason to do it is to accommodate poorly made accessibility software then count me out. That's bad reasoning and the 'correct' elements will change with the accessibility software.

Logically it should be the reverse. Screenreaders can learn how to detect all clickable elements instead of shoehorning a form control element into places.

The main thesis seems to be that the user should be able to press View Source and understand what's going on. I agree, at least for web sites. For web apps, at least anything over 50 lines, you are probably going to want to use a typed language. (Well, you could technically use .js with TypeScript compiler and type annotations in special comments but I did not find that very pleasant.)

I used to be really big on this, though (and it makes me sad that these days most sites are 1 big unreadable line of HTML). In fact, I find a beauty and elegance in shipping the whole thing as a single HTML file with no dependencies (1 network request!), though I did eventually make a "build system" (my build system is cat) so I could have a sane editing experience. Boom, self-contained portable software in 1 human-readable file!

Along the same lines, I think the coolest thing about web development is that you can make your first (interactive!) programs with Notepad and whatever browser ships with your machine. (Just drag the HTML file onto the browser!) It's magic!

Edit: Just found an unexpected benefit of self-contained HTML: makes your software immune to bit rot. I tried loading an old project of mine on Web Archive but it hadn't archived the external JS file! Sad! Meanwhile, this one loads fine because all the JS is in the HTML! Winning!

https://web.archive.org/web/20210508133239id_/https://andai....

This is my homage to the old SodaPlay Constructor. (Never made an editor, sorry!) Feel free to view-source!

I don’t believe the author is advocating for single file systems, but I don’t want to speak for them.
Sorry, I didn't mean to imply this! My original comment had "I even go so far as to..." but it got lost somewhere in editing.
I'm sceptical on this: by now there are lots of ways to "peek behind the curtain" in the developer panel: we have the DOM view, network tab, heap view, built-in javascript prettifyer. Sure, "view source" is still important, but I'd question if its importance is still as absolute as the HTMX people make it out to be.
I wanted to show people how easy it is to do cool things with a computer, how low the barrier to entry is.* One HTML file. Your OS's built in text editor and browser. You look at the code and you can see it there in front of you! It isn't obfuscated. It isn't even minified. Everything is right there, all together. You can just save the file and drag it onto your browser. No Git, no zipped project folders. No build system! No server! (No MIME type errors!).

The "frictionlessness" of lowering the "activation energy", is not just nice for beginners... heck, it's nice for me! I can just download this file from Wayback Machine and continue hacking on it!

It does, of course, limit you to very small codebases, but that's what I like! Many small projects. The spring physics creature linked above is about 300 LOC total. The ASCII bonsai tree is ~100: https://web.archive.org/web/20220823113003id_/https://andai....

*In terms of tooling/setup, at least! Learning to code is another matter... (Neither of these projects are very readable for a beginner though, so that aspect needs some work.)

> In fact, I find a beauty and elegance in shipping the whole thing as a single HTML file with no dependencies (1 network request!)

This is even easier now we have 'data:' URLs. It's also useful for avoiding problems on file:// URLs, which don't even need a HTTP server.