Van11y (for Vanilla-Accessibility) is a collection of accessible scripts for rich interfaces elements, built using progressive enhancement and customisable.
Wednesday, October 21st, 2020
Collusion between three separate services owned by the same company: the Google search engine, the YouTube website, and the Chrome web browser.
Gosh, this kind of information could be really damaging if there were, say, antitrust proceedings initiated.
In the meantime, use Firefox
Tuesday, October 20th, 2020
I’ve been like a dog with a bone the way I’ve been pushing for a declarative option for the Web Share API in the shape of
button type=“share”. It’s been an interesting window into the world of web standards.
The story so far…
- I blogged some half-formed thoughts.
- Then I opened an issue on the spec for the Web Share API.
- Meanwhile I wrote a polyfill, releasing the code and a test.
- I responded to pushback I was getting on the issue I filed.
- I also wrote up an explainer document so everything is gathered in one place.
- Finally I started soliciting feedback from people using the Web Share API in order to gather data.
That’s the situation currently. The general consensus seems to be that it’s probably too soon to be talking about implementation at this stage—the Web Share API itself is still pretty new—but gathering data to inform future work is good.
In planning for the next TPAC meeting (the big web standards gathering), Marcos summarised the situation like this:
Not blocking: but a proposal was made by @adactio to come up with a declarative solution, but at least two implementers have said that now is not the appropriate time to add such a thing to the spec (we need more implementation experience + and also to see how devs use the API) - but it would be great to see a proposal incubated at the WICG.
Like I said, I’m not expecting anything to happen anytime soon, but it would be really good to gather as much data as possible around existing usage of the Web Share API. If you’re using it, or you know anyone who’s using it, please, please, please take a moment to provide a quick description. And if you could help spread the word to get that issue in front of as many devs as possible, I’d be very grateful.
(Many thanks to everyone who’s already contributed to that issue—much appreciated!)
Monday, October 19th, 2020
Continuous partial browser support
That’s not what happened though. Developers used vendor-prefixed properties as though they were stable. Tutorials were published that basically said “Go ahead and use these vendor-prefixed properties and ship it!” There were even tools that would add the prefixes for you so you didn’t have to type them out for yourself.
Browsers weren’t completely blameless either. Long after features were standardised, they would only be supported in their prefixed form. Apple was and is the worst for this. To this day, if you want to use the
clip-path property in your CSS, you’ll need to duplicate your declaration with
-webkit-clip-path if you want to support Safari. It’s been like that for seven years and counting.
Like capitalism, vendor prefixes were one of those ideas that sounded great in theory but ended up being unworkable in practice.
Still, developers need some way to get their hands on experiment features. But we don’t want browsers to ship experimental features without some kind of safety mechanism.
- Developers are able to register for an experimental feature to be enabled on their origin for a fixed period of time measured in months. In exchange, they provide us their email address and agree to give feedback once the experiment ends.
- Usage of these experiments is constrained to remain below Chrome’s deprecation threshold (< 0.5% of all Chrome page loads) by a system which automatically disables the experiment on all origins if this threshold is exceeded.
I think it works pretty well. If you’re really interested in kicking the tyres on an experimental feature, you can opt in to the origin trial. But it’s very clear that you wouldn’t want to ship it to production.
You could ship something that’s behind an origin trial, but you’d have to make sure you’re putting safeguards in place. At the very least, you’d need to do feature detection. You certainly couldn’t use an experimental feature for anything mission critical …but you could use it as an enhancement.
And that is a pretty great way to think about all web features, experimental or otherwise. Don’t assume the feature will be supported. Use feature detection (or
@supports in the case of CSS). Try to use the feature as an enhancement rather than a dependency.
If you treat all browser features as though they’re behind an origin trial, then suddenly the landscape of browser support becomes more navigable. Instead of looking at the support table for something on caniuse.com and thinking, “I wish more browsers supported this feature so that I could use it!”, you can instead think “I’m going to use this feature today, but treat it as an experimental feature.”
You can also do it for well-established features like
geolocation. Instead of assuming that browser support is universal, it doesn’t hurt to take a more defensive approach. Assume nothing. Acknowledge and embrace unpredictability.
The debacle with vendor prefixes shows what happens if we treat experimental features as though they’re stable. So let’s flip that around. Let’s treat stable features as though they’re experimental. If you cultivate that mindset, your websites will be more robust and resilient.
Friday, October 16th, 2020
Take a look at your smartphone and delete all the apps you don’t really need. For many tasks, you can use a browser on your phone instead of an app.
Privacy-wise, browsers are preferable, because they can’t access as much of your information as an app can.
Thursday, October 15th, 2020
This in an intriguing promise (there’s no code yet):
A PWA typically requires writing a service worker, an app manifest and a ton of custom code. Progressier flattens the learning curve. Just add it to your html template — you’re done.
Wednesday, October 14th, 2020
I added a long-overdue enhancement to The Session recently. Here’s the scenario…
You’re on a web page with a comment form. You type your well-considered thoughts into a
textarea field. But then something happens. Maybe you accidentally navigate away from the page or maybe your network connection goes down right when you try to submit the form.
This is a textbook case for storing data locally on the user’s device …at least until it has safely been transmitted to the server. So that’s what I set about doing.
My first decision was choosing how to store the data locally. There are multiple APIs available:
localStorage. It was clear that
sessionStorage wasn’t right for this particular use case: I needed the data to be saved across browser sessions. So it was down to
IndexedDB is the more versatile and powerful—because it’s asynchronous—but
localStorage is nice and straightforward so I decided on that. I’m not sure if that was the right decision though.
Alright, so I’m going to store the contents of a form in
localStorage. It accepts key/value pairs. I’ll make the key the current URL. The value will be the contents of that
textarea. I can store other form fields too. Even though
localStorage technically only stores one value, that value can be a JSON object so in reality you can store multiple values with one key (just remember to parse the JSON when you retrieve it).
Now I know what I’m going to store (the
textarea contents) and how I’m going to store it (
localStorage). The next question is when should I do it?
I could play it safe and store the comment whenever the user presses a key within the
textarea. But that seems like overkill. It would be more efficient to only save when the user leaves the current page for any reason.
Alright then, I’ll use the
unload event. No! Bad Jeremy! If I use that then the browser can’t reliably add the current page to the cache it uses for faster back-forwards navigations. The page life cycle is complicated.
In either case, just adding a listener for the event could screw up the caching of the page for back-forwards navigations. I should only listen for the event if I know that I need to store the contents of the
textarea. And in order to know if the user has interacted with the
textarea, I’m back to listening for key presses again.
But wait a minute! I don’t have to listen for every key press. If the user has typed anything, that’s enough for me. I only need to listen for the first key press in the
addEventListener accepts an object of options. One of those options is called “
once”. If I set that to
true, then the event listener is only fired once.
So I set up a cascade of event listeners. If the user types anything into the
textarea, that fires an event listener (just once) that then adds the event listener for when the page is unloaded—and that’s when the
textarea contents are put into
I’ve abstracted my code into a gist. Here’s what it does:
- Cut the mustard. If this browser doesn’t support
localStorage, bail out.
- Set the
localStoragekey to be the current URL.
- If there’s already an entry for the current URL, update the
textareawith the value in
- Write a function to store the contents of the
localStoragebut don’t call the function yet.
- The first time that a key is pressed inside the
textarea, start listening for the page being unloaded.
- When the page is being unloaded, invoke that function that stores the contents of the
- When the form is submitted, remove the entry in
localStoragefor the current URL.
That last step isn’t something I’m doing on The Session. Instead I’m relying on getting something back from the server to indicate that the form was successfully submitted. If you can do something like that, I’d recommend that instead of listening to the form submission event. After all, something could still go wrong between the form being submitted and the data being received by the server.
Still, this bit of code is better than nothing. Remember, it’s intended as an enhancement. You should be able to drop it into any project and improve the user experience a little bit. Ideally, no one will ever notice it’s there—it’s the kind of enhancement that only kicks in when something goes wrong. A little smidgen of resilient web design. A defensive enhancement.
Tuesday, October 13th, 2020
My name is Jeremy Keith and I endorse this message:
I love the modern JS platform (the stuff the browser does for you), and hate modern JS tooling.
Thursday, October 8th, 2020
Tess calls for more precise language—like “site” and “origin”—when talking about browsers and resources:
When talking about web features with security or privacy impact, folks often talk about “first parties” and “third parties”. Everyone sort of knows what we mean when we use these terms, but it turns out that we often mean different things, and what we each think these terms mean usually doesn’t map cleanly onto the technical mechanisms browsers actually use to distinguish different actors for security or privacy purposes.
Tuesday, October 6th, 2020
The “Adjust CSS” slider on this delightful homepage is an effective (and cute) illustration of progressive enhancement in action.
Monday, October 5th, 2020
The reason for a share button type
If you’re at all interested in what I wrote about a declarative Web Share API—and its sequel, a polyfill for button type=”share”—then you might be interested in an explainer document I’ve put together.
It’s a useful exercise for me to enumerate the reasoning for
button type=“share” in one place. If you have any feedback, feel free to fork it or create an issue.
The document is based on my initial blog posts and the discussion that followed in this issue on the repo for the Web Share API. In that thread I got some pushback from Marcos. There are three points he makes. I think that two of them lack merit, but the third one is actually spot on.
Apart from placing a button in the content, I’m not sure what the proposal offers over what (at least one) browser already provides? For instance, Safari UI already provides a share button by default on every page
But that is addressed in the explainer document for the Web Share API itself:
The browser UI may not always be available, e.g., when a web app has been installed as a standalone/fullscreen app.
That’s exactly what I wanted to address. Browser UI is not always available and as progressive web apps become more popular, authors will need to provide a way for users to share the current URL—something that previously was handled by browsers.
That use-case of sharing the current page leads nicely into the second bit of pushback:
The API is specialized… using it to share the same page is kinda pointless.
But again, the explainer document for the Web Share API directly contradicts this:
Sharing the page’s own URL (a very common case)…
Rather than being a difference of opinion, this is something that could be resolved with data. I’d really like to find out how people are currently using the Web Share API. How much of the current usage falls into the category of “share the current page”? I don’t know the best way to gather this data though. If you have any ideas, let me know. I’ve started an issue where you can share how you’re using the Web Share API. Or if you’re not using the Web Share API, but you know someone who is, please let them know.
Okay, so those first two bits of pushback directly contradict what’s in the explainer document for the Web Share API. The third bit of pushback is more philosophical and, I think, more interesting.
The Web Share API explainer document does a good job of explaining why a declarative solution is desirable:
That’s also my justification for having a declarative alternative: it would be easier for more people to use. I said:
At a fundamental level, declarative technologies have a lower barrier to entry than imperative technologies.
That’s demonstrably false and a common misconception: See OWL, XForms, SVG, or any XML+namespace spec. Even HTML is poorly understood, but it just happens to have extremely robust error recovery (giving the illusion of it being easy). However, that’s not a function of it being “declarative”.
He’s absolutely right.
I’ve been using the word “declarative” when I actually meant “robust in handling errors”.
I’ve been using “declarative” as a shorthand for “either HTML or CSS”, but really I should try to be more precise in my language. The word “declarative” covers a wide range of possible languages, and not all of them lower the barrier to entry. A declarative language with a brittle error-handling model is as daunting as an imperative language.
With that in mind,
button type=“share” is worth pursuing. Yes, it’s a declarative option for using the Web Share API, but more important, it’s a robust option for using the Web Share API.
I invite you to read the explainer document for a share button type and I welcome your feedback …especially if you’re currently using the Web Share API!
Saturday, October 3rd, 2020
A great talk by Ethan called The Design Systems Between Us.
Thursday, October 1st, 2020
Did you know there’s an
imagesrcset attribute you can put on
link rel="preload" as="image" (along with an
I didn’t. (Until Amber pointed this out.)
This is a superb twenty minute presentation by Trys! It’s got everything: a great narrative, technical know-how, and a slick presentation style.
Conference organisers: you should get Trys to speak at your event!
Employing the principle of least power for better digital preservation:
New frameworks and technologies spring up to try and cope with the speed of change. More and more ways to build and release things faster and cheaper becomes the norm. And, the more this happens, the more we deviate from standards: good ol’ HTML and CSS.
Tuesday, September 29th, 2020
This is a great way to use a service worker to circumvent censorship:
After the visitor opens the website once over a VPN, the service worker is downloaded and installed. The VPN can then be disabled, and the service worker will take over to request content from non-blocked servers, effectively acting as a proxy.
Monday, September 28th, 2020
A great presentation on taking a sensible approach to web development. Great advice, as always, from the blogging machine that is Chris Ferdinandi.
The web is a bloated, over-engineered mess. And, according to developer and educator Chris Ferdinandi, many of our modern “best practices” are actually making the web worse. In this talk, Chris explores The Lean Web, a set of principles for a simpler, faster world-wide web.
Sunday, September 27th, 2020
The title says it all, really. This is another great piece of writing from Paul Ford.
I’ve noticed that when software lets nonprogrammers do programmer things, it makes the programmers nervous. Suddenly they stop smiling indulgently and start talking about what “real programming” is. This has been the history of the World Wide Web, for example. Go ahead and tweet “HTML is real programming,” and watch programmers show up in your mentions to go, “As if.” Except when you write a web page in HTML, you are creating a data model that will be interpreted by the browser. This is what programming is.
Saturday, September 26th, 2020