State of HTML 2023 for PHP Folks

The inaugural State of HTML survey was released this year and it was incredible. Its main purpose is of course to collect information about developers’ knowledge of and experience with HTML features. But it also happens to be a fantastic resource for learning about HTML. Even as someone who loves HTML there was so much in there I didn’t know about.

I guarantee that anyone who works with HTML-related code – whether it’s JavaScript, PHP, Ruby, or anything else – will benefit from going through the survey. So go take it!

Note: you can’t actually take the survey anymore. But you can still go through it and see all the questions, which is all you need.

PHP User Group Talk

I recently gave a talk at the local PHP User Group about the survey and limited the scope to HTML features that are:

  1. Relevant to back-end folks, especially those who do templating.
  2. Usable in production today (over 90% browser support or safe to use as progressive enhancement).

There’s a demo site that goes along with the talk which you can see here, and get the source code here. The site has some notes but it was really meant to be a companion for the talk, so I’ll post some additional context below. The best way to go about this is probably to read this blog post before browsing the demo site or the source code.

Demo A: capture Attribute

This is a way to capture and upload media directly to a file input from a mobile device. It’s supported by an impressive 99.5% of mobile browsers, which is probably the highest support I’ve ever seen for something I’ve looked up on Caniuse.

Note: total browser support is much lower because this is only meant for mobile devices.

The demo site simply links to the MDN doc, which has a good demo. At the risk of stating the obvious: make sure you open it on a mobile device.

Demo B: Handy Interactive Elements

This demo has pretty good notes on the demo site, but what’s missing is the code. For the talk, there was a live coding demo that showed how to use the different features discussed here. But for you, the source code and MDN docs will have to suffice. 🙃

A few notes for additional context:

  • The buttons demo different features of the <dialog> element and Popover API.
  • Corner popover: simply demos popover styling.
  • Open/close popover buttons: demo separate buttons for opening and closing.
  • Manual popover: demos a popover with no “light dismiss”.
  • Dialog popover: demos a combination of the <dialog> element and Popover API, so you get the best of both worlds. This is most noticeable with the effects on focus trapping, navigation order, and Esc key dismissing.
  • Extra button: this is just there to demonstrate how focus navigation order is affected by the Popover API.

The <details> and <dialog> elements have excellent browser support, but Popover API support is only in the high 70’s. I think it’s the only exception to the “can be used today” criterion for the talk. I included it anyway because it’s so useful!

Demo C: Web Components

Web Components are arguably more about JavaScript than HTML. Creating them requires a non-trivial amount of JS, even if you use a library like Lit. But they still fit comfortably under the “HTML-related web standards” umbrella so here we are.

The main benefit is that they’re framework agnostic. This allows you to do things like:

  • Use the same components across multiple websites.
  • Rebuild a site in a different stack but keep using the components you already have.

Web Components have similar features to other component systems (React, Vue, Blade, etc), including:

  • Slots
  • Properties
  • Events
  • Methods

And if you don’t want to roll your own, you can use a library like Shoelace. A lot less work and you still get the same benefits! Creating a Web Component was beyond the scope of this talk because it’s complicated, so this “demo” was basically just a plug for Shoelace. 😅

But Wait, There’s More


Tell the browser to lazy load an image or iframe.


A way to create a list of suggestions for an input.

How it differs from <select>:

  • Can be used with several types of inputs.
  • Typing filters the list.
  • User can enter an arbitrary value.

View on MDN.

inert attribute

Completely disables interaction with an element and its descendants and hides them from assistive devices.


Only 71% support, but can be a progressive enhancement.

Tells the browser to block rendering until a resource is loaded and evaluated.

Stylesheets and scripts in <head> automatically block rendering already. But in some cases it’s useful to be explicit:

  • Critical fonts added via <link>.
  • Stylesheets and scripts inserted dynamically by other scripts.
  • Async scripts for things like A/B testing. Allows these to load asynchronously but still waits for them to finish evaluating before rendering.

fetchpriority attribute

Only 70% support, but can be a progressive enhancement.

Tells the browser to prioritize loading a resource over others, thereby enabling some control over how images and linked resources load.