HTML Can Do That
173 points by abhin4v
173 points by abhin4v
I'm a fan of HTML over JS when possible, but I developed skepticism for things like this until I've had firsthand success with them.
A few years ago I heard about datalist and thought it was great, so I went to use it and found it was only implemented if you said the input was of type "email". I thought that was strange and looked up why and, if I remember correctly, the HTML spec abstractly described the requirements but gave only one concrete example, which was email addresses, so that's what browsers implemented.
I'm surprised by that as I've been using them happily for over a decade. Was it a particular browser?
Firefox is the main holdout, sadly. Most browsers have support by 2020.
You can see on https://caniuse.com/datalist and sort by “Date Relative”
Huh, I had no idea firefox doesn't support it for time inputs. And I'm a firefox user!
That isn't what the previous person was saying though, they described a much more dire situation.
This would have been some time between 2018 and 2020, which is right around the time I switched back from Chrome to Firefox, so it could have been either of those.
I believe this was the StackOverflow comment I was thinking of, but I don't know whether the linked standard has been updated updated.
I made an @-mention autocomplete for a no-JS fediverse client using datalist and multiple inputs that reveal themselves one by one as the previous one becomes filled out. Works like a charm for other things IMO.
What I hate about all of this is that so much depends on IDs. When I work on parts of a web page, be it using React or manually writing HTML or using some template engine, I want to reason locally. By using a feature where references between nodes happens through IDs (as opposed to through parent/child relationships or sibling relationships), I need to reason globally. IDs are global, so you need to "allocate" a global ID and make sure to not accidentally re-use one you've used before.
Reducing global reasoning and focusing on ways to enable local reasoning is, IMO, one of the primary ways to keep a code base maintainable and comprehensible across years of evolution. It's why types are so effective: you can reason locally as long as you have a type definition available; you don't need to think about the parts of your code base which produces a value in order to work on the parts which consume a value.
In React, you could in principle have an ID allocator in JavaScript to gain back some of that local reasoning, or generate UUIDs for IDs, though I've never seen anyone do that in practice. But when writing HTML or using template engines, that would all have to manually taken care of by the programmer.
Also, am I the only one who thinks it's weird that it's on button to have a popovertarget? If they wanted to let a button control a <details> section, would they add a new detailstarget attribute to button? Wouldn't it make more sense for a button to just have a target to which it sends an activation event, so that it's on the receiver to decide how it acts when activated? This goes back to local reasoning again, just in terms of a standard rather than a program; why does the standard make it so that the section defining the <button> element has to know about the section defining <div ... popover>?
Reducing global reasoning and focusing on ways to enable local reasoning is, IMO, one of the primary ways to keep a code base maintainable and comprehensible
I strongly agree.
In React, you could in principle have an ID allocator in JavaScript
Use the useId() hook. Generating random unique IDs for elements doesn't work with mixed server & client side HTML generation like Next.js does: the server and client will generate different random IDs for the same elements and you get hydration errors.
import {useId} from 'react';
const MyFormRow = () => {
const inputId = useId();
return (<div class="form-row">
<input type="text" id={inputId} />
<label htmlFor={inputId}>Blah blah blah</label>
</div>);
}
Hey that looks useful! I don't write a lot of React and when I do I don't tend to use HTML features which rely on ID, but it's good to know in case it does come up.
It was added a while ago because it was direly necessary for accessibility, because loads of the aria attributes rely on element id attributes too.
Grouped
<details>
I have never yet seen this used for good. There are definitely situations where it’s suitable, but they’re rare. In the typical accordion situation, there’s not actually any reason to close the others.
For quite some time after Firefox implemented it, it retained the dom.details_group.enabled pref, so I could opt out of <details name> working, but they removed the pref eventually, so now I can just fume and wonder whether it’s time to write a user script to purge <details name> attributes. Or maybe it can be done in a uBlock Origin filter, I think it might be possible.
<datalist>
Unfortunately not as useful as one might like. A bit of an odd duck, really, handled wildly inconsistently across platforms. Not useless by any means, but also probably not usable for what you have in mind.
Another thing: why on earth does this article put <code tabindex="0"> on the code blocks? Bizarre and obviously wrong.
Grouped details is used here for the "caches" dropdown, and IMO it would be a good match for the "flag" dropdown.
Yeah, I learned that was details last month due to a style conflict.¹ <details> was never particularly appropriate there, though it was the best option for five or more years, and a popover is the appropriate technique now. I should contribute a patch to that effect, for all such places.
¹ I find the default line-height excessive, especially on the home page. 430d864b0d7bf1b30913ee42e6cca3d9fbddcaa4 was a dubious change with a technique bad but normally invisible, but which became messily visible with the reduced line-height, so I investigated.
(I should acknowledge then: okay, that’s arguably used for good, but it wasn’t a great implementation—a backdrop summary::before { position: fixed; inset: 0 } is probably a better technique, though not entirely equivalent—and is definitely no longer appropriate.)
For what's worth, I use <details> all the time in GitHub PR comments.
<details> is great, but you can also group them by doing something like <details name="...">, and now all of the <details> boxes on the same page with the same name will be grouped together. Specifically, if you open one, it'll automatically close all of the others. The works well for accordions, but... you probably don't want accordions (or if you do, you should let the user open them all at the same time if they want).
As an experiment to see how far HTML/CSS without JS can go I started textlog.cc and I’m honestly surprised how far we’ve gone and how many features we’ve implemented without introducing JS. The compressed HTML payload stays below 10kb on each request which makes it quite fast to navigate. Popovers with lazy OG image loading, helpers and such, honestly if nobody told you, you wouldn’t immediately see that it doesn’t use JS. HTML can do plenty.
In Safari default date picker is awful.
Native datepickers are awful everywhere, to the point that gov.uk has its own implementation: https://design-patterns.service.justice.gov.uk/components/date-picker/
The native datepickers on Firefox for Windows and Firefox for Android are pretty good and also respect my locale instead of defaulting to that weird Sunday-first thing that some countries have.
Oh wow, the native colourpicker on FA is really shit. It's just a list of 9 colours to pick from.
It's just a list of 9 colours to pick from.
You slander it! Give it a value other than the nine, and it’s a list of ten!
What they replace them with is frequently worse. More than occasionally, they don’t let you just type a date, even if their thing places an <input type=text> there with format like DD/MM/YYYY specified.
The MOJ design system differs from the GOV.UK one in that respect: https://design-system.service.gov.uk/components/date-input/
I prefer the gov.uk one, but I guess it would get annoying for lots of dates
But those components serve a different purpose. The date input you linked is for numeric dates you can easily remember (like birthdate) but can't easily pinpoint the day of the week. The calendar is when you need to know the date relative to a week day, e.g. planning a trip.
I decided to be conservative and say only about Safair which is PITA.
Thanks to LLM I can rebuild everything™ (I'm not frontend engineer, so for me this is acceptable).
On desktop, all pickers are awful. But on mobile they’re much better/feel more native. I have a feeling ideally you’d need a two-way solution, serve the native on mobile and a better one on desktop. That would introduce JS however.
Another discussion on the same subject (for posterity): https://lobste.rs/s/fng667/replacing_js_with_just_html
Cool, but as always, all these APIs are awkward or you just have to know how they work to be able to use them. The default look for these things on the web are also just terrible somehow. Every day I'm more convinced that the web should be nuked at some point and just be maintained as a legacy transitional thing that we eventually dump altogether.
you just have to know how they work to be able to use them
Not to be facetious, but isn't that through of most APIs?
Not to be facetious
That isn't even facetious, that's just stating reality. "This X is awkward, you have to know how it works to be able to use it" is a bizarre complaint on any topic.
The basics of literally any tool in existence since man started attaching rocks to the end of sticks, is that you have to know how they work to use them.
I love these being technically feasible. I have the social problem, though, that no matter how much you can do with plain, easy-to-maintain HTML, a business customer will ask for some feature that requires a big pile of javascript.
Datalist is too bad or buggy to use. Even on this website the list of options changes opacity in strange ways.
It's great to see HTML having come along so far to evolve towards having more of the JavaScript equivalents, which were so tricky to get right ~20 years ago. I had a mixture of PTSD and delight while scrolling through this article!
My browser is Firefox 154.0, but I can't get over the amount of UI/UX issues I see on my work Macbook Air M3 on a daily basis vs my 5 year old Linux laptop. Just for UI/UX issues that cropped up from reading this article:
Every day I add more to my list of Mac UI inconsistencies - blog post coming soon!