MicroLighter; HTML Can Do That (Now); The 2026 HTML Boilerplate
The Clankers, for the most part, build really awful things for the web and lean heavily on giant frameworks like React, since that’s in the bulk of the training data and also due to the fact that the elites helping them take over knowledge work were born and raised on it and similar ilk.
So, we’ve got two resources that take us back to (modern) HTML basics (and ones we regularly re-up when they change, here at the Drop) and also look at something that scratches a particular itch for me: syntax highlighters; or, in this case, a new one that uses a relatively new CSS standard (plus a little JS) to accomplish the task.
MicroLighter

Every syntax highlighter you’ve probably reached for – Prism, highlight.js, Shiki – works by rewriting your <code> block into a small (well, sometimes yuge) forest of <span> tags, each carrying a class like token keyword. It’s fine and it worked for ages, but it also means the DOM you authored isn’t the DOM on the page anymore, which creates diff noise, reflow on large documents, and the particular headache of editable code (i.e., if the text node is gone, replaced by markup, you can’t trivially stick contenteditable on it and re-highlight on input).
MicroLighter sidesteps the whole approach by using the CSS Custom Highlight API, which landed in Baseline 2025 (I’ve seen some notes it was in 2024 but we’ll stick with what MDN says). Instead of injecting spans, it registers Range objects against the original Text node and groups them into named Highlight objects – then styling happens entirely through ::highlight(<category>) pseudo-elements in CSS. Your markup stays untouched, and all colors come from the CSS cascade.
The tokenizer in highlight.js (the core file in this project, not the competing project with that name) runs a recursive scanRegion() function that expands good ol’ TextMate grammar rules, finds the earliest-matching rule via nextRule(), and hands ranges to addRange() and addCaptures() to build the highlight sets. It uses the browser’s native RegExp engine with the d, g, and m flags vs. impose (more capable?) dependencies such as Onigurumao or WebAssembly. This is a deliberate trade-off since another restriction baked into the project is that the CI flow places a hard limit of 2,100 bytes on dist/microlighter.min.js. This means MicroLighter cannot express everything Oniguruma can, and complex language grammars won’t tokenize as accurately as Shiki’s.
Grammar loading happens on-demand via dynamic import() – grammar-dependencies.js maintains a loadingLanguages map to deduplicate fetches, resolves aliases (js → javascript, gql → graphql), and transitively fetches any source.* or text.* includes that a grammar declares. So, a page showing only CSS loads only css.js.
Themes are pure CSS – a [data-syntax-theme="github"] block sets --syntax-* custom properties using light-dark() to cover both schemes in one file, and the actual ::highlight() rules just point at those variables. The JS has zero knowledge of colors, which means anyone who can write a custom property map can author a theme.
You can choose from one of three integration paths: a programmatic API (highlightAll() returning a promise), a side-effectful auto-runner for the CDN/no-build crowd, and a <micro-lighter> web component that adds copy buttons and a line-number gutter via ::part(), with the code kept in light DOM so the highlighter can still find the text node.
I spent some time with it and came away fairly impressed by the elegance of the design. Every constraint reinforces the others: zero runtime dependencies, tiny footprint, on-demand grammars, pure-CSS themes, and a DOM that stays editable.
However, if you need full TextMate fidelity for a production editor, Shiki’s still the call. But for documentation sites, personal tools, or anything where you want live editable code snippets, MicroLighter’s a keeper.
You can get a feel for it on the landing page of the project.
HTML Can Do That (Now)

The browser platform has been quietly eating JavaScript’s lunch for a few years, and it’s picking up pace. Chris Burnell did a solid survey of native HTML attributes and elements that replace what we used to need entire libraries for (while also noting some accessibility foibles of the modern counterparts). We’ll take a brief look here at what Chris documented, but you’ll need to go to Chris’ site for the live examples.
The most immediately useful one (imo) is the popover attribute. Drop popover on any element, wire a button to it via popovertargetaction, and you’ve got light-dismiss, ESC-to-close, and automatic top-layer stacking – no z-index arithmetic or JS required. The browser handles focus management and layering. If you’ve ever debugged a tooltip that kept disappearing under a sticky header because some ancestor had overflow: hidden, you know exactly how welcome this is.
<dialog> has def been around longer but gets a meaningful upgrade when you pair it with <form method="dialog">. The form submission closes the modal declaratively, no JS required. You still get .showModal() and .close() for the programmatic path when you need it, and combining <dialog> with popover gives you an HTML-only open/close cycle that would’ve taken a React component and a state variable two years ago.
Grouped <details> for exclusive accordions was a pretty cool “TIL”. Give multiple <details> elements the same name attribute and the browser enforces mutual exclusivity (i.e., opening one closes the others). It’s accordion behavior without a single line of JavaScript, which is pretty spiffy.
The command and commandfor attributes (the Invoker Commands spec) deserve some attention even though they’re still settling and are kind of “in the weeds”. They decouple a trigger button from its target element, so you can have separate show and hide buttons for a single popover. The stable surface so far covers show-modal, close, request-close, toggle-popover, show-popover, and hide-popover, with media controls and clipboard copy apparently on the roadmap – which would be pretty cool if they land cleanly.
loading="lazy" on images replaces the (ugh) IntersectionObserver dance most of us are/were doing by hand. It’s browser-native, no polyfill required, and works on <img> and related elements. This is a “use it everywhere” type of idiom, and it would be cool to see it land in Typst, Quarto, and other such publishing systems by default.
hidden="until-found" is more niche but also super handy now that it’s now baked-in. This attribute hides content until the browser’s in-page search or a fragment link targets it, at which point the hidden attribute is auto-removed. This is a super clever hack for FAQ-style accordions where you want CMD-F or CTRL+F to surface hidden answers. The caveat is that screen-reader search behavior is inconsistent, so it’s unfortunately not production-ready for anything where accessibility matters (which should be most situations imo).
The shakier entries in this catalog – <input type="color|date|range">, <progress>, <meter>, and <datalist> – also ship built-in but come with the well-documented problem that cross-browser styling varies wildly and accessibility audits tend to surface real gaps. Adrian Roselli’s “Under-Engineered Comboboxen” covers the <datalist> situation thoroughly, and his conclusion is “mebbe wait.” I tend to agree, and it feels like these might be specs that got to the finish line before the implementation quality did.
The through-line across all of this is that the core web platform is reclaiming UI primitives that JS libraries formerly owned (by necessity). popover, <dialog>, grouped <details>, and loading="lazy" are production-ready and I’d suggest getting familiar with all of them so you can use them regularly. For the rest, watch the space, but don’t ship them without a proper accessibility audit first.
The 2026 HTML Boilerplate

Manuel Matuzović updated his HTML boilerplate for 2026, five years after his original version. It’s a complete <head> template with a line-by-line explanation of every element, marked as required, essential, or optional, so you can understand the reasoning before deciding what to keep.
Some notable additions since the 2021 version include the new text-scale meta tag for respecting mobile OS text sizing, a rel="alternate" type="text/markdown" link for serving content to LLMs, site.standard.publication for the Atmosphere, and fediverse:creator for Mastodon author attribution.
There’s also updated guidance on SVG favicons with dark-mode support, Safari 26’s changed theme-color behavior, and an expanded “other noteworthy elements” section covering Open Graph details, preloading, RSS, notch handling, and viewport resize behavior.
It’s a practical, opinionated starting point rather than a minimal one, but you’ll learn a ton just from poring over it and adopting what you need.
FIN
Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:
- Mastodon via
@dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev - Bluesky via
<https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy>
☮️
Leave a Reply