The details / summary thing absolutely kills me. There’s basically nothing you can’t do with them. Hiding and replacing markers is easy. But every component library just pretends they don’t exist.
It even saves you the effort of all the aria control and expanded tags: these tags don’t need them.
That is no longer true! You can do it in CSS with a combination of `@starting-style` and `transition-behavior: allow-discrete`. [1]
Another gotcha you'll run into is animating the height. A couple other new features (`interpolate-size: allow-keywords` and `::details-content`) will let you get around that. [2]
Seriously. As a user I can count on zero hands the number of times I’ve said “Oh great, I’m sure glad this UI is animated!” - and likewise zero times have I missed it when animation isn’t used. Animation is a way to light small units of your users’ precious time on fire, for zero benefit.
As the other user alluded to, Animations are not actually there for people who are comfortable using a computer. The vast majority of users are borderlines in capable of using the internet these days. Animations are supposed to be there to really help guide these users into understanding what the scary machine is doing when they click it. Can they be overused, absolutely, but i think have an accordion fold out animated is a reasonable case. You gotta remember your average user isnt paying any fucking attention, so drawing their attention to important changes on screen is not only good but necessary. I'd prefer no animations ever, but i also dont own an iphone while the majority of the world either does or wants to.
Animations are also a way to explain causal relationships between interactions and their results, and to help build mental models of software behaviour.
> Animating the details element is tricky. By the spec, browsers don’t natively support transitions between display: none and display: block.
Very hot take; then don't animate them!
Animation in a UI is great - you draw the user's attention to a widget that changed because they might not necessarily notice it otherwise. This improves the UX.
With a details/summary, the animation is not needed and can only make a negative change to the UX. There is no positive change to the UX that animating the details/summary elements would bring. When it is opened it is obvious.
If you really really need to animate the details, instead of animating open/close, instead animate the summary background/text color to indicate that the element has just changed state.
Would I like easy animation of open/close? Sure. Does it improve the UX? Nope.
Details works even when it's set display:contents too, for even more flexibility. Can't animate from open›close, yet, though. That's pretty much my last frustration with it.
I think the CSS support for that has finally landed, though it means targetting a pseudo element instead. Its been a year, so support is probably good enough you don't care if just the animation doesn't happen.
Note that the transition to `auto` in that post relies on `interpolate-size` which has yet to land on Firefox or Safari, and neither have movement right now.
Yes. For example, on Codidact (https://codidact.com), limited HTML access is offered along with Markdown when making posts, and the details and summary tags in particular are whitelisted. I've made extensive use of this in some of my content, for example https://software.codidact.com/posts/289251/289252#answer-289... . If you have NoScript you can easily verify that the expanding sections work perfectly well without JavaScript. They can even be nested, as they are here; and the summary text can contain some other forms of markup without issue. (When crafting the post, however, I had to do some tricky things with whitespace to avoid confusing the Markdown parser.)
You can't actually control the open state properly from markup (the `open` attribute only sets the default state), which is why I haven't bothered with them.
I’m not sure this is correct. The DOM class HTMLDetailsElement has the `open` property, which you can use to read/write the details element’s state. If you’re using setAttribute/getAttribute just switch to the property.
Having to use the property on the element instance, rather than the actual HTML attribute, is exactly the kind of wrapper code I want to avoid if I'm using a built-in.
If you specify the same name on each `details` element they behave like an accordion automatically [1], no need for JavaScript. If you set one of them to open that one will be initially open.
Brilliant I will be adopting a few of these, I have been on a personal quest to reduce js use recently, I feel like I spend more time debugging js than producing the end result.
Most of this is great, except for the input/datalist bits, which are not sufficiently functional to be used in any real scenario. Users expect these interfaces to be tolerant of misspellings, optional sub text under each option, mobile ux niceties, etc -- and so everyone builds this with js...
My main beef with datalist is that there's no easy way to show and allow only text (e.g. Beverly Hills), but have the actual value selected be a number (e.g. 90210). In other words there's no analogy to <option value="90210">Beverly Hills</option>.
> Each <option> element should have a value attribute... It can also have a label attribute, or, missing that, some text content, which may be displayed by the browser instead of value (Firefox), or in addition to value (Chrome and Safari)... The exact content of the drop-down menu depends on the browser, but when clicked, content entered into control field will always come from the value attribute
This seems... underspecified. Not ideal that Chrome/Safari aren't aligned with Firefox here, and that there is no standard way to only display the label
That and there's no HTML way to interactively load results. Or are you really going to serialize half a million records to HTML and transfer it all every time the relevant block is added to a page? What if it sits in the header or footer templates?
One thing I am quite hopeful for is customizable selects! It's in WHATWG stage 3 right now. I have seen so many horrors with javascript-based custom dropdowns components. https://developer.chrome.com/blog/a-customizable-select
HTML and JavaScript serve distinct purposes, making better or worse comparisons logically flawed. Complex/interactive web apps requires JavaScript, period. Attempting to build sophisticated apps solely through HTML (looking at you HTMLX) eventually hits a functional ceiling.
I assume you mean htmx. It doesn't have to be either/or. You can supplement htmx with Javascript.
The core idea with htmx is that you transfer hypertext with controls and structure built in, not just a JSON blob that requires additional context to be useful.
I have just shipped a very useful and interactive app surprisingly quickly for my customer using just htmx with a little Javascript.
I dont think anyone is arguing Google Earth should be pure HTML. But it is equally false you cant do Gmail with HTML only.
There are things that HTML could do, and should be doing, that is not done or not yet possible simply due to hype and trend from browser vendors. We could continue to polish HTML + sprinkle of Javascript to its absolute maximum before hitting JS Apps. Right now this is far from the case.
Hey the email services has just proved you could offer better than Gmail experience with HTML + small dose of JS. Another example being the new FE on Github.
At the end of the day it isn't really the tech that is the problem. Is how people use the tech. And for thousands of different reasons keeping it simple has always provided better experience evaluated on the whole.
Depends on how complex it is meant to be. Just like many wordpress sites that could easily have been static websites, many javascript heavy sites could have easily just have been using htmlx.
If your need really, goes beyond what htmx offers, then you may need Javascript. But in my experience people tend to use the tools they know for their job, not the tools that would be best suited.
It shouldn't have to be this way though. There is no reason html can't do things it needs to do to build complete apps. We could use reasonable defaults to allow a new type of html markup without JavaScript.
All the http verbs.
Decent html input controls
What else?
Plain HTML is very cozy to me - I came of age in that era. Marquee tags 4eva.
But as much as I hate to admit it, it is very difficult to build something functional today with plain HTML and no/minimal JS. If you want, say, a model form that manages its children as well, you're basically going to end up with a 2003-era ASP-feeling application with way too many views and forms (as seen on your employer's current HR system). Or you use HTMX... and you still end up with just as many (partial) views, but now with so much implicit state that you're veering into write-only code.
I dislike modern JS to the extent that I opted for Phoenix LiveView, just so I could achieve interactivity without ever having to touch JS, but in truth it's not a comprehensive solution. Still had to write a web worker, a bridge to handle things like notifications, etc. Plus the future direction of Phoenix, all in on AI, is worrying.
Honestly, I should probably just swallow my disdain and learn to appreciate and use modern JS, as painful as that sounds. I want to write and release cool things, not get caught up in navel-gazing language wars.
> But as much as I hate to admit it, it is very difficult to build something functional today with plain HTML and no/minimal JS.
I would certainly agree that using a little JS can get you further than just HTML. But I think that a plain HTML page is far more pleasant to use (and thus, functional) than the JS monstrosities that dominate the Web today. There's a reason people use the NoScript addon: because a whole lot of website designers use JS in ways that make the experience a ton worse for the user.
It's not an either/or. Modern Javascript is actually really nice to write and use, and you can write it in a tight, minimal way that doesn't bloat the page or slow it down.
> Or you use HTMX... and you still end up with just as many (partial) views, but now with so much implicit state that you're veering into write-only code.
You're overthinking htmx then. I do some fairly complex stuff with no extra partials. Trick is just always rerender and use hx-select and hx-target to slice out the bits you want to update on the current page.
Server always has authoritative state and code is dead simple to reason about.
I appreciate the helpful reply, but I think this is precisely the kind of indirection I need to avoid. I'm a sucker for elegance. If left entirely to my own devices I'd probably design a language / write a transpiler of my own, and wind up with exceedingly elegant tooling for websites, and no websites. :)
This is why I don't use Typescript or frameworks in my own projects, I just constantly seek the cleanest abstraction and never get anything done. Using a deliberately messy solution is annoying but at least I accomplish stuff.
Until your client tells you that it doesn't work in Edge and you find out it's because every browser has its own styling and they are impossible to change enough to get the really long options to show up correctly.
Then you're stuck with a bugfix's allotment of time to implement an accessible, correctly themed combo box that you should have reached for in the first place, just like what you had to do last week with the native date pickers.
I was trying to rewrite some UI library with html sometime ago following the W3C accessibility specs and found out a lot of patterns can’t be done with pure html and require javascript unfortunately.
If we've concluded that's it's okay to have elements that change/morph, as we seem to with the introduction of things like details, a native tab-like element feels like a glaring omission. Tabs have been a long-standing UI pattern and forcing every site to implement their own is a nightmare for accessibility. (The page you're reading is maybe already in a browser tab.)
I wouldn't be surprised if it turned out less than half of the custom tab interfaces on the web failed from an accessibility standpoint. When considering ARIA guidance, I don't even think it's possible to build an accessible version in HTML alone.
Other people have recognized it's missing. Open UI has a draft spec for it[0] and CSS Tricks has an article from 2001 about Open UI's experiments with sections for tabs[1]. I have no idea what happened on this front, though.
And yes, being able to do all of these in pure HTML/CSS would be awesome. Though we are getting there with things like `details` and the newer `popover` features which should make things like rich tooltips, menu buttons, etc. a lot easier to implement. IIRC, there are also several anchor CSS properties to make positioning a lot simpler.
It's great until you have a typo in the field, or want to show options that don't start with what you typed in but appear near the end of an option (think Google search's autocomplete). There's no way to filter in Javascript and force it to show certain options with <datalist>. I've resorted to <ol> for search suggestions.
I don't see any mention of HTTP 204 or multipart/x-mixed-replace. Those are both very helpful for implementing rich JavaScript-free HTML applications with advanced interactivity.
I didn't know about <datalist>, but how are you supposed to use it with a non-trivial amount of items in the list? I don't see how this can be a replacement for javascript/XHR based autocomplete.
> If we can hand-off any JS functionality to native HTML or CSS, then users can download less stuff, and the remaining JS can pay attention to more important tasks that HTML and CSS can't handle (yet).
Your blogs have very small amount solution, but the JS use cases are very large. How this little replacement can do more thing? I usually like the idea of being using as lean as possible, if it's can be possible to do more thing just with HTML and CSS that's obviously cool. Is it really possible to replace JS with HTML in near future?
BTW the toggle solution (expanding content) is good.
Use a checkbox, d. Define vars for light mode. Override when checked for dark mode with body:has(#d:checked) and can include the dark mode media query too
Why would you build a switch instead of relying on the user’s system settings? The only reason I can imagine is that your dark/light mode is not usable/readable so it forces the user to switch
Something I keep thinking about when I consider the trade-offs between building a site with HTML/CSS wherever possible vs JS is what the actual _experience_ of writing and maintaining HTML/CSS is vs JS. JS gets knocked around a bunch compared to "real" languages (although less so in recent years), but at the end of the day, it's a programming language. You can write a loop in it.
Writing a web server in C++ is a way to get excellent performance. So why don't most people do it?
Some of these new HTML features don't fully work in my "ancient" browser. But all of them partially work (ie opening the accordion element doesn't close others but it still opens and closes) and they still remain functional elements I can read and interact with. This puts them far ahead of any javascript implementation which almost universally fail to nothing.
I'm so not impressed by the toggle implementation... How nice it could have been.
Nesting the elements is a truly hideous choice. The summary is part of the details?? I thought they were opposites.
Should we also put the headings in the <p> from now on?
Identifying a target should be done by id or by name. That it does use a name because js can't target it without makes it even more stupid.
We already had labels for form fields. Inventing a completely different method for something very similar is a dumb idea. The old checkbox hack is more flexible and less ugly for some implementations.
Why force the hidden content to be below or above the toggle? We aren't gaining anything with this.
What is this nonsense for an element to not just be hidden or displayed but to have some weird 3rd state where only one of its children is shown?
How should styling it even work for this new state? If I apply a style to the hidden content it must also apply to the link? The text is hidden but the style is visible??? Preposterous!
Don't try style <details> to avoid unexpected behavior. Try wrapping the hidden content in a new element to make it behave normally.
What is this ugly arrow? If you find 1000 websites using a toggle I doubt there is one using an ugly arrow like that.
The default styling gives no clue about it being clickable?
The pointer (awkwardly called the cursor) choice is the text selection?????
Blue underlined "more" is what everyone does and everyone is used to. The cursor should be pointer. (This is css speak for "the pointer should be a hand")
The number of js toggles you can find online where the button lives inside the hidden text is guaranteed to be zero. Forget about drop in replacement, you will have to reinvent your css.
Maybe I'm dense but I also want my url to reflect the state of the page. I would have been impressed if that was supported. Personally I use actual links and disable default action in the listener if js is enabled/working or modify the state on the server if js isn't available/working.
It would have been great if the toggle action was implemented as a simple attribute something like toggle="element name" so that anything can be clickable and anything can be toggleable. Have a "closed" as well as an "open" attribute for the target.
Doesn't seem very hard. An open/closed attribute would be useful for other things too. Using display:none is terrible as display: is used for many things.
> Nesting the elements is a truly hideous choice. The summary is part of the details?? I thought they were opposites.
It gives them a semantic connection. Last I checked, HTML isn't really based on giving special meaning to combinations of sibling tags. A summary is part of the thing that conceptually requires detailing.
> If you find 1000 websites using a toggle I doubt there is one using an ugly arrow like that.
I think the default looks fine. But TFA clearly explains right there that it can be styled. (Specifically, by styling ::before on the summary tag.)
> The default styling gives no clue about it being clickable?
You asked what the arrow is, and then asked about the lack of indication that the summary header is clickable. The arrow is exactly that indication.
> Maybe I'm dense but I also want my url to reflect the state of the page.
If you scroll, should the fragment automatically update as you scroll past anchors? I think I'd find that quite annoying.
I really try not using JavaScript unless absolutely needed. On my latest project, the whole site actually functions without JavaScript and is server side rendered. However, there's some small piece which I really needed JavaScript for couple reasons.
Basically, I have a site which collects the top STEAMD posts from places like HN, lobsters, tildes, slashdot, bear, reddit etc and displays them in chronological order. I wanted a way for users to block posts with certain keywords or from specific domains. I didn't want to do this server side for both performance reasons plus privacy reasons. I didn't want users to need signing up or something to block. I also didn't want to collect block lists for privacy reasons. So, I resorted to using JavaScript and local storage. All posts within the filter for the date are sent and JavaScript is used to block posts with keywords before displaying. So my server never knows what keywords are blocked.
The problem is that it's difficukt to style or animate those things. Unless you're builsing something for dun or technical where it's not important it's fine but i doubt any real world commercial project would be satisfied with just this
It even saves you the effort of all the aria control and expanded tags: these tags don’t need them.
Animating the details element is tricky. By the spec, browsers don’t natively support transitions between display: none and display: block.
Another gotcha you'll run into is animating the height. A couple other new features (`interpolate-size: allow-keywords` and `::details-content`) will let you get around that. [2]
Modern CSS is awesome.
[1] https://developer.chrome.com/blog/entry-exit-animations
[2] https://nerdy.dev/open-and-close-transitions-for-the-details...
If you really need to detect whether it's supported there are hacky methods: https://www.bram.us/2024/07/11/feature-detect-css-starting-s...
In general I find animations on the web overused and unnecessary
Very hot take; then don't animate them!
Animation in a UI is great - you draw the user's attention to a widget that changed because they might not necessarily notice it otherwise. This improves the UX.
With a details/summary, the animation is not needed and can only make a negative change to the UX. There is no positive change to the UX that animating the details/summary elements would bring. When it is opened it is obvious.
If you really really need to animate the details, instead of animating open/close, instead animate the summary background/text color to indicate that the element has just changed state.
Would I like easy animation of open/close? Sure. Does it improve the UX? Nope.
https://developer.chrome.com/blog/styling-details
https://developer.mozilla.org/en-US/docs/Web/API/HTMLDetails...
[1] https://developer.mozilla.org/en-US/blog/html-details-exclus...
This seems... underspecified. Not ideal that Chrome/Safari aren't aligned with Firefox here, and that there is no standard way to only display the label
[from]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
Like I get this is a blog system but it still feels odd, especially for a "use this plain HTML"-style post...
It seems to link to the authors codepen. If you us code pen you can bookmark the snippets. Codepen colorizes the html/css etc.
Link rot is a thing though, so it’s not always ideal to have dependencies on third party urls staying the same.
The core idea with htmx is that you transfer hypertext with controls and structure built in, not just a JSON blob that requires additional context to be useful.
I have just shipped a very useful and interactive app surprisingly quickly for my customer using just htmx with a little Javascript.
There are things that HTML could do, and should be doing, that is not done or not yet possible simply due to hype and trend from browser vendors. We could continue to polish HTML + sprinkle of Javascript to its absolute maximum before hitting JS Apps. Right now this is far from the case.
At the end of the day it isn't really the tech that is the problem. Is how people use the tech. And for thousands of different reasons keeping it simple has always provided better experience evaluated on the whole.
If your need really, goes beyond what htmx offers, then you may need Javascript. But in my experience people tend to use the tools they know for their job, not the tools that would be best suited.
All the http verbs. Decent html input controls What else?
But as much as I hate to admit it, it is very difficult to build something functional today with plain HTML and no/minimal JS. If you want, say, a model form that manages its children as well, you're basically going to end up with a 2003-era ASP-feeling application with way too many views and forms (as seen on your employer's current HR system). Or you use HTMX... and you still end up with just as many (partial) views, but now with so much implicit state that you're veering into write-only code.
I dislike modern JS to the extent that I opted for Phoenix LiveView, just so I could achieve interactivity without ever having to touch JS, but in truth it's not a comprehensive solution. Still had to write a web worker, a bridge to handle things like notifications, etc. Plus the future direction of Phoenix, all in on AI, is worrying.
Honestly, I should probably just swallow my disdain and learn to appreciate and use modern JS, as painful as that sounds. I want to write and release cool things, not get caught up in navel-gazing language wars.
I would certainly agree that using a little JS can get you further than just HTML. But I think that a plain HTML page is far more pleasant to use (and thus, functional) than the JS monstrosities that dominate the Web today. There's a reason people use the NoScript addon: because a whole lot of website designers use JS in ways that make the experience a ton worse for the user.
Yet most people don't.
There are some problems with the language itself but it's mostly from a users perspective that I find it frustrating.
You're overthinking htmx then. I do some fairly complex stuff with no extra partials. Trick is just always rerender and use hx-select and hx-target to slice out the bits you want to update on the current page.
Server always has authoritative state and code is dead simple to reason about.
It's good to know these things exist so there are alternatives to reaching for a fat react component as the first step.
Then you're stuck with a bugfix's allotment of time to implement an accessible, correctly themed combo box that you should have reached for in the first place, just like what you had to do last week with the native date pickers.
In short: you can’t have an interactive popover (e.g. a toast notification) on top of a dialog modal.
I’d love to use the new native elements but we’re sadly not quite there yet.
I wouldn't be surprised if it turned out less than half of the custom tab interfaces on the web failed from an accessibility standpoint. When considering ARIA guidance, I don't even think it's possible to build an accessible version in HTML alone.
Other people have recognized it's missing. Open UI has a draft spec for it[0] and CSS Tricks has an article from 2001 about Open UI's experiments with sections for tabs[1]. I have no idea what happened on this front, though.
[0] https://open-ui.org/components/tabs/
[1] https://css-tricks.com/newsletter/281-tabs-and-spicy-drama/
We still should do more with HTML and CSS! And reach for leaner solutions than React everywhere.
But be careful going for a pure CSS solution for things like tabs if you don’t understand the accessibility requirements.
(I wish the HTML spec would move faster on these common patterns!)
And yes, being able to do all of these in pure HTML/CSS would be awesome. Though we are getting there with things like `details` and the newer `popover` features which should make things like rich tooltips, menu buttons, etc. a lot easier to implement. IIRC, there are also several anchor CSS properties to make positioning a lot simpler.
It's great until you have a typo in the field, or want to show options that don't start with what you typed in but appear near the end of an option (think Google search's autocomplete). There's no way to filter in Javascript and force it to show certain options with <datalist>. I've resorted to <ol> for search suggestions.
Expecting users to press modifiers when clicking on these is so funny.
BTW the toggle solution (expanding content) is good.
Its so easy, like a breeze!
Writing a web server in C++ is a way to get excellent performance. So why don't most people do it?
Because they already wrote it in C.
Apache and Nginx are both written in C. Together they run 57.7% of all web servers:
https://w3techs.com/technologies/overview/web_server
Nesting the elements is a truly hideous choice. The summary is part of the details?? I thought they were opposites.
Should we also put the headings in the <p> from now on?
Identifying a target should be done by id or by name. That it does use a name because js can't target it without makes it even more stupid.
We already had labels for form fields. Inventing a completely different method for something very similar is a dumb idea. The old checkbox hack is more flexible and less ugly for some implementations.
Why force the hidden content to be below or above the toggle? We aren't gaining anything with this.
What is this nonsense for an element to not just be hidden or displayed but to have some weird 3rd state where only one of its children is shown?
How should styling it even work for this new state? If I apply a style to the hidden content it must also apply to the link? The text is hidden but the style is visible??? Preposterous!
Don't try style <details> to avoid unexpected behavior. Try wrapping the hidden content in a new element to make it behave normally.
What is this ugly arrow? If you find 1000 websites using a toggle I doubt there is one using an ugly arrow like that.
The default styling gives no clue about it being clickable?
The pointer (awkwardly called the cursor) choice is the text selection?????
Blue underlined "more" is what everyone does and everyone is used to. The cursor should be pointer. (This is css speak for "the pointer should be a hand")
The number of js toggles you can find online where the button lives inside the hidden text is guaranteed to be zero. Forget about drop in replacement, you will have to reinvent your css.
Maybe I'm dense but I also want my url to reflect the state of the page. I would have been impressed if that was supported. Personally I use actual links and disable default action in the listener if js is enabled/working or modify the state on the server if js isn't available/working.
It would have been great if the toggle action was implemented as a simple attribute something like toggle="element name" so that anything can be clickable and anything can be toggleable. Have a "closed" as well as an "open" attribute for the target.
Doesn't seem very hard. An open/closed attribute would be useful for other things too. Using display:none is terrible as display: is used for many things.
It gives them a semantic connection. Last I checked, HTML isn't really based on giving special meaning to combinations of sibling tags. A summary is part of the thing that conceptually requires detailing.
> If you find 1000 websites using a toggle I doubt there is one using an ugly arrow like that.
I think the default looks fine. But TFA clearly explains right there that it can be styled. (Specifically, by styling ::before on the summary tag.)
> The default styling gives no clue about it being clickable?
You asked what the arrow is, and then asked about the lack of indication that the summary header is clickable. The arrow is exactly that indication.
> Maybe I'm dense but I also want my url to reflect the state of the page.
If you scroll, should the fragment automatically update as you scroll past anchors? I think I'd find that quite annoying.
Basically, I have a site which collects the top STEAMD posts from places like HN, lobsters, tildes, slashdot, bear, reddit etc and displays them in chronological order. I wanted a way for users to block posts with certain keywords or from specific domains. I didn't want to do this server side for both performance reasons plus privacy reasons. I didn't want users to need signing up or something to block. I also didn't want to collect block lists for privacy reasons. So, I resorted to using JavaScript and local storage. All posts within the filter for the date are sent and JavaScript is used to block posts with keywords before displaying. So my server never knows what keywords are blocked.
Site for anyone curious:
https://limereader.com/