Behavior belongs in the HTML
unplannedobsolescence.com
unplannedobsolescence.com
In the `too-short-message` example where is the `not-long-enough` message defined?
Then we run off into microformats, they're great, but out of scope (and never tied back).
The button extension using custom attributes should be getting attribute `message` (not `type`).. but that's probably a typo. A potentially more reasonable attribute would be `title` since in many desktop browsers you'll get a hover tooltip (which might be beneficial, although for the contrived example perhaps not.. on the other hand, why would you want a multitude of alert buttons?)
And then there's zero consideration for Content-Security-Policy[0], one of the current reasons you'd avoid inline JS (`unsafe-inline`) in favour of script tags that can have `nonce-*` or `sha256-*` signed content.
As for CSP, my point isn't really that you should be throwing `onclick`s on everything, it's more that you should think of HTML as the place to define most of the page's behavior (where appropriate) using elements and attributes. A script tag could implement that interface too.
There are loads of web apps that have rich interactivity where mixing presentation with supporting logic creates a real mess. Say you’ve got a grid with a million (gasp!) rows. You’re really gonna emit all that unnecessary inline JS behavior over the wire?! Why on Earth?? What if you need context binding? You could just have a jQuery .on handler registered once at the parent and filtered to all buttons, which pulls the id of the record from a data-attribute on the target element, finishing the same work in a couple of lines of code in one easy to maintain spot. Yes, adding addEventListener code all over your app would be repetitive and wasteful, but that (amongst browser incompatibilities) is why jQuery was invented, but you can hand roll your own utility or use HTMX or a million concise tools to do this. Including a right-sized dependency isn’t going to kill you. Sure, if you’ve got a stupidly simple HTML page with a couple elements with a handler or two, fine, go ahead, knock yourself out. I disagree with this one-size-fits-all assertion. We did a lot of this before and it sucked.
What ever happened to modesty in juniors or apprentices?
Maybe too many of us just age out and leave the industry :-/
This article is explicitly a defense of the interface that htmx (which I am a core maintainer for) employs. I think more JS libraries should use attributes as their interface. As for when and where that's appropriate, well, like anything, it depends on the context, but I'm confident in saying it's appropriate in more contexts than it is currently being used.
Registering thousands of event handlers on one screen can have performance impact, and is generally why registering them on individual elements becomes a problem for an interactive page. Registering on a parent element can provide the same interactivity with only a single handler thanks to event bubbling.
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Bu...
JSX and templating in other frameworks gives you that desirable locality, which I think is why it can feel so painful to go back to vanilla js.
I still default to plain ol' vanilla JS on a lot of things, but having to add definitions to elements after first grabbing them with selectors is annoying, particular for singular elements.
A lot of the related complaints -- including some in this article -- basically boil down to the old complaint about object oriented programming: "everything happens somewhere else" so what's actually going on isn't something you can read in one place, you either have to wind your way through the various scope/inheritance contexts to build up a picture of the code/rules in play, or you need to have tooling do it for you.
Or... you put it inline, mixing concerns, and eventually discover the tradeoff that comes with that choice.
But you can’t look at a piece of HTML and know for sure it doesn’t have an event bound to it without reading every scrap of JS (or just running the code). In OOP at least you (should) have some guarantees of encapsulation. But since I don’t see an obvious way to make HTML more OO, I can see the appeal of a declarative style.
But I'm not doing anything massively complicated yet, so I don't know how it scales for complex UI interactions.
[0]: https://github.com/codewithkyle/supercomponent/blob/master/s...
Edit: if signals are your jam you could us https://github.com/maverick-js/signals
The larger components contain their own state, and communicate by events (so component Foo emits a change event when its state changes, and component Bar listens for that event and fetches the new state by checking event.target.data).
It's working reasonably well with this relatively small set of interactions. But I can see a point where I'll have to create a Flux/Vuex-style state store and use actions to mutate it.
Too much of this industry is dogmatic pursuit of absolutes. The submission notes the documentation declaring that one should never use event attributes, arguing an illusory separation. Similar sorts of absolutism can be found in almost every tactic and approach. Too often many seek to simplify the choices we need to constantly make by making some of the options verboten. Its why everything old is new again and we seem to constantly have camps reverting to forbidden approaches and now decrying their replacements as the bad option.
I don't think behavior belongs exclusively in the HTML. There are types of webapps and complex UIs that require some form of involved state management and HTML—or, more generally, Hypertext as the Engine of Application State—is not the right solution for that. In that sense I want this post to be against the dogma of "behavior exclusively belongs in JavaScript," because I think that's incorrect and it's a pretty common view, even from expert sources that I respect.
I am, however, somewhat dogmatic in believing that web pages whose behavior can be described declaratively, in the HTML, using built-in attributes or a carefully selected superset of additional attributes, absolutely should be. This is because declarative interfaces almost always last longer and require less maintenance (I plan to write about and explore this topic in a lot more detail). A great many web pages that are not written this way could be, and suffer from an increased maintenance burden as a result.
I think a good middle ground here is that HTML web components article that was shared here a few weeks ago: https://gomakethings.com/html-web-components/
I like this because it's still fairly low-code but you get cool stuff out of the box like attributeChangedCallback. You don't have to mess with build tools, which is what I like the most about this strategy. I can just drop these components into my Rails views like any other element, and their custom functionality gets mounted up as soon as they get folded into the DOM. No more document.querySelectorAll(".foo-bar").forEach(foo => bar()). Much cleaner, and the intent is more clear too. With <foo-bar>, it's much more obvious that the element has scripting attached to it than <div class=”foo-bar">.
Still though, I like it in theory. JSX still feels closer to an “ideal” syntax to me, even if there’s a lot to complain about there as well.
Definitely more work to be done in this area though, and I tried to keep this post mostly theoretical for that reason.
[0]: https://htmx.org/essays/no-build-step/#developer-experience
I will say TS source mapping gives me a near identical experience to debugging JS. Even if it’s another artefact to cart around, it’s near invisible once set up. It feels close enough to the actual code I write.
While a debugger looking at an HTMX app does show exactly what is running at that moment, it peels back the mental model HTMX sets up to reveal the inner workings. That I feel like could be more confusing for folks learning.
Thanks for making cool stuff though! :) (genuine! The internet can be a snarky place)
The naive and inexperienced will follow those trends, and will generate countless "why I stopped using..." and "... considered harmful" blog posts 1-2 years from now, when frustrated, they'll flip on their God and declare them Satan.
Those who have been through these cycles before will smile, shake their head and know there's nothing that can be said to dissuade them, until they learn painfully from their own experience. And the wheel keeps turning.
For the record, behavior doesn't "belong" anywhere. The optimal solution varies based on the type of project and content. Considering the historical baggage of HTML and how specific it is to the browser, while many apps are multiplatform these days, I could easily argue HTML is the worst place to put your behavior.
https://html.spec.whatwg.org/multipage/custom-elements.html
You can go ahead and create <whatever> <custom-elements> with whatever attributes you want and it'll work.
(I didn't click on the link because I was focused on absorbing your article in one go; now that I've looked at the link, I think that your sentence is much more concise for the reader.)
For those of us who remember working with "DHTML" before libraries like jQuery proliferated, and then jQuery became ubiquitous for a few years - many of us recall the messes that the simplistic technique of using intrinsic events gave us.
When intrinsic events were introduced (e.g. the onclick attribute), they were meant to wire up some simple DOM behavior to Java Applets. Then somebody convinced the W3C people that it was a neat idea, and it needed to be in the HTML 4 spec.
I love html, and I love writing nice clean markup that clearly defines a document, so that you can look at the html without css and js and know what information it is presenting to you. I really don't want it to do anything else.
For the internet of the shopping mall you would use HTMX or some such and that should be enhanced or pimped to the max by all means. Inline, webassembled and reactified riding the tailwind. Go for it, knock yourselves out and make a killing. How about bigger screens for all the popups?
need more buttons
So although you're right that it does a bit more, it wasn't and probably shouldn't be used for other than document presentation over the web.
That's the reason javascript got introduced: the custom designed and dynamic parts.
Its is also redescribing well defined concepts subjectively but presenting them objectively, and this is unfortunately a constraint that eliminates the value of the article.
Ty.
Just wanted to let you know OP.