Tags: html

984

Wednesday, April 29th, 2026

Two Paradigms for Enhancing HTML Tags | That HTML Blog

This really gets to the heart of one of the biggest benefits of HTML web components: composability. You can nest your regular markup inside multiple custom elements; something that is can’t do.

The other exciting approach doesn’t exist yet: custom attributes. Again, they’d be a great way of using composability to turbo-charge your existing HTML in all sorts of ways.

Thursday, April 23rd, 2026

Tuesday, April 21st, 2026

Alistair Davidson / validation-enhancer · GitLab

Here’s another nice progressive web component for your forms, this time for showing error messages.

Never Lose Form Progress Again :: Aaron Gustafson

Here’s an excellent progressive web component from Aaron—wrap a custom element around your exising form and your good to go:

At its core, form-saver is a small web component that wraps a form, keeps an eye on it, stores values in localStorage, and restores them when the page loads again. Better yet, it clears out saved data after a successful submission so you’re not accidentally resurrecting stale information the next time someone stops by.

Thursday, March 26th, 2026

The Great CSS Expansion | Butler’s Log

Web development follows a familiar cycle. First we glue together a solution with whatever we have — JavaScript, image hacks, Flash, anything. Then the platform matures, and CSS or HTML eventually makes that same workaround native. Rounded corners, custom fonts, smooth scrolling, sticky positioning: all of these started as JavaScript-heavy hacks before CSS turned them into a single declaration.

We are in another one of those transition moments. A new wave of long-requested CSS features is finally landing, and many of them are explicitly designed to replace patterns that used to require JavaScript. Not as approximations — as first-class platform primitives that handle the edge cases, run in the right thread, and need zero dependencies.

Progressive Web Components | Ariel Salminen

I’m slapping my forehead—progressive web components is a perfect name for what I’ve been calling HTML web components. Why didn’t I think of that?

A Progressive Web Component is a native Custom Element designed in two layers: a base layer of HTML and CSS that renders immediately, without JavaScript, and an enhancement layer of JavaScript that adds reactivity, event handling, and more advanced templating.

Monday, March 9th, 2026

Testing browser support for `focusgroup`

In my previous post, I mentioned that I’ve used the web install API in production. Specifically, I’ve used it on The Session. In order to do that, I had to register for the origin trial.

I’ve just signed up for another origin trial. This time it’s for the proposed focusgroup attribute:

The focusgroup HTML attribute is a proposed declarative way to add keyboard arrow-key navigation to composite widgets such as toolbars, tablists, menus, listboxes, etc. without writing any roving-tabindex JavaScript. One attribute replaces hundreds of lines of boilerplate.

I’ve got an HTML web component on The Session called tab-controls. And yes, there’s a bunch of code in there to listen for keyboard events and respond appropriately. I would very much like to rip that code out.

So now that I’ve opted into the origin trial, I’ve added this to my HTML:

<tab-controls role="tablist" focusgroup="tablist">

If this focusgroup attribute takes off, I’ll be able to remove the role attribute but for now, it’s very much needed.

In the JavaScript for my tab-controls custom element, I need to be able to detect support for focusgroup. Here’s how I’m doing it:

if (!this.focusgroup) {
// do all my key handling stuff here
}

Here’s the important thing: don’t use getAttribute('focusgroup') to test for browser support. That will return true if the attribute is in the HTML. But the attribute will only get converted into a property if the browser understands it.

Jake has a lot more detail on the differences between attributes and properties.

Anyway, I figured I’d share that little snippet in case you too were interested in trying out the focusgroup proposal using progressive enhancement.

Friday, February 20th, 2026

Performance-Optimized Video Embeds with Zero JavaScript – Frontend Masters Blog

This is a clever technique for a CSS/HTML only way of just-in-time loading of iframes using details and summary.

Wednesday, February 18th, 2026

Reduce the JS Workload with no- or lo-JS options

This is an excellent one-stop shop of interface patterns:

This is an organic collection of common JS patterns that can be replaced with just HTML, CSS, and no, or very low, JS. As HTML and CSS continue to mature, this collection should expand.

Tuesday, January 27th, 2026

699: Jeremy Keith on Web Day Out – ShopTalk

This episode of the Shop Talk Show is the dictionary definition of “rambling” but I had a lot of fun rambling with Chris and Dave!

Tuesday, January 20th, 2026

Sunday, January 18th, 2026

The datalist element on iOS 26

The datalist element is all fucked up on iOS. Again.

I haven’t “upgraded” my iPhone to iOS 26 and I have no plans to. The whole Liquid Glass thing is literally offputting. So I wouldn’t have known about the latest regression in Safari if a friend hadn’t texted me about the problem.

He was trying to do a search on The Session. He was looking for the tune, The Road To Town. He started typing this into the form on the home page of the site. He got as far as “The Road To”. That’s when the entire input was obscured by a suggestion from the associated datalist.

A screenshot of The Session on an iPhone during a search on the homepage. The search input is completely obscured by the text: The Road To Lisdoonvarna.

This is incredibly annoying and seems to be a pattern of behaviour for Safari. Features are supported …technically. But the implementation is so buggy as to be unusable.

I’ll probably have to do some user-agent sniffing, which I hate. And it won’t be enough to just sniff for Safari on iOS 26. Remember that every browser on iOS is just Webkit in a trenchcoat.

Time to file a bug and then wait God knows how long for an update to get rolled out.

Update: I filed a bug, but in the meantime it looks like user-agent sniffing is going to be impossible.

Wednesday, December 17th, 2025

Dynamic Datalist: Autocomplete from an API :: Aaron Gustafson

Great minds think alike! I have a very similar HTML web component on the front page of The Session called input-autosuggest.

Why we teach our students progressive enhancement | Blog Cyd Stumpel

Progressive enhancement is about building something robust, that works everywhere, and then making it better where possible.

NoLoJS: Reducing the JS Workload with HTML and CSS - Web Performance Calendar

You might not need (much) JavaScript for these common interface patterns.

While we all love the power and flexibility JS provides, we should also respect it, and our users, by limiting its use to only what it needs to do.

Yes! Client-side JavaScript should do what only client-side JavaScript can do.

Sunday, December 7th, 2025

The Web Runs On Tolerance – Terence Eden’s Blog

Spot-on observations from Terence linking the fundamental nature of parsing in web browsers with the completely wrong-headed takes of some technologists who have built on top of the web.

Saturday, November 29th, 2025

Installing web apps

Safari, Chrome, and Edge all allow you to install websites as though they’re apps.

On mobile Safari, this is done with the “Add to home screen” option that’s buried deep in the “share” menu, making it all but useless.

On the desktop, this is “Add to dock” in Safari, or “Install” in Chrome or Edge.

Firefox doesn’t offer this functionality, which as a shame. Firefox is my browser of choice but they decided a while back to completely abandon progressive web apps (though they might reverse that decision soon).

Anyway, being able to install websites as apps is fantastic! I’ve got a number of these “apps” in my dock: Mastodon, Bluesky, Instagram, The Session, Google Calendar, Google Meet. They all behave just like native apps. I can’t even tell which browser I used to initially install them.

If you’d like to prompt users to install your website as an app, there’s not much you can do other than show them how to do it. But that might be about to change…

I’ve been eagerly watching the proposal for a Web Install API. This would allow authors to put a button on a page that, when clicked, would trigger the installation process (the user would still need to confirm this, of course).

Right now it’s a JavaScript API called navigator.install, but there’s talk of having a declarative version too. Personally, I think this would be an ideal job for an invoker command. Making a whole new install element seems ludicrously over-engineered to me when button invoketarget="share" is right there.

Microsoft recently announced that they’d be testing the JavaScript API in an origin trial. I immediately signed up The Session for the trial. Then I updated the site to output the appropriate HTTP header.

You still need to mess around in the browser configs to test this locally. Go to edge://flags or chrome://flags/ and search for ‘Web App Installation API’, enable it and restart.

I’m now using this API on the homepage of The Session. Unsurprisingly, I’ve wrapped up the functionality into an HTML web component that I call button-install.

Here’s the code. You use it like this:

<button-install>
  <button>Install the app</button>
</button-install>

Use whatever text you like inside the button.

I wasn’t sure whether to keep the button element in the regular DOM or generate it in the Shadow DOM of the custom element. Seeing as the button requires JavaScript to do anything, the Shadow DOM option would make sense. As Tess put it, Shadow DOM is for hiding your shame—the bits of your interface that depend on JavaScript.

In the end I decided to stick with a regular button element within the custom element, but I take steps to remove it when it’s not necessary.

There’s a potential issue in having an element that could self-destruct if the browser doesn’t cut the mustard. There might be a flash of seeing the button before it gets removed. That could even cause a nasty layout shift.

So far I haven’t seen this problem myself but I should probably use something like Scott’s CSS in reverse: fade in the button with a little delay (during which time the button might end up getting removed anyway).

My connectedCallback method starts by finding the button nested in the custom element:

class ButtonInstall extends HTMLElement {
  connectedCallback () {
    this.button = this.querySelector('button');
    …
  }
customElements.define('button-install', ButtonInstall);

If the navigator.install method doesn’t exist, remove the button.

if (!navigator.install) {
  this.button.remove();
  return;
}

If the current display-mode is standalone, then the site has already been installed, so remove the button.

if (window.matchMedia('(display-mode: standalone)').matches) {
  this.button.remove();
  return;
}

As an extra measure, I could also use the display-mode media query in CSS to hide the button:

@media (display-mode: standalone) {
  button-install button {
    display: none;
  }
}

If the button has survived these tests, I can wire it up to the navigator.install method:

this.button.addEventListener('click', async (ev) => {
  await navigator.install();
});

That’s all I’m doing for now. I’m not doing any try/catch stuff to handle all the permutations of what might happen next. I just hand it over to the browser from there.

Feel free to use this code if you want. Adjust the code as needed. If your manifest file says display: fullscreen you’ll need to change the test in the JavaScript accordingly.

Oh, and make sure your site already has a manifest file that has an id field in it. That’s required for navigator.install to work.

Wednesday, November 26th, 2025

The only frontend stack we should talk about

Explore the platform. Challenge yourself to discover what the modern web can do natively. Pure HTML, CSS, and a bit of vanilla JS…

Thursday, November 13th, 2025

Reimagine the Date Picker – David Bushell – Web Dev (UK)

This is a superb way to deprecate a little JavaScript library. Now that you can just use HTML instead, the website for Pikaday has been turned into a guide to choosing the right design pattern for your needs. Bravo!

Pikaday is no longer a JavaScript date picker. Pikaday is now a friendly guide for front-end developers. I want to push developers away from the classic date picker entirely. Especially fat JavaScript libraries.

Tuesday, November 11th, 2025

DOCTYPE magazine 🚀⌨️

’80s BASIC type-in mags are back, but this time for HTML!

10 wonderful web apps, including games, toys, puzzles and utilities

No coding knowledge needed, you just type