Accessibility
Building an accessible search page with progressive enhancements
This article documents what I learned building a search page for stocks, ETFs, and other securities for https://jch.app. I start with built-in HTML elements and attributes for accessibility, add CSS for layout and visual design, and progressively enhance the user experience with Turbo, and one line of javascript. At the end, I'll talk about some experiments that led to dead ends and share interesting links and references.
aria-label or title? Screen Reader Behaviour Explained
Discover how screen readers handle aria-label
vs title
attributes. Get clear guidance on implementation and accessibility standards.
CSS
Prevent scrollbar jump
With modal components, it’s common/expected to prevent the background from scrolling.
However, if your page was long enough that there were visible scrollbars, they disappear when you set overflow
to hidden
, which causes the layout to shift horizontally. Sometimes it’s hard to see behind the modal backdrop, but it’s often visible and a bit jarring.
The scrollbar-gutter
CSS property tells the browser to reserve space for a scrollbar, even when one isn’t visible. It can be used to prevent that visual shift.
Why :is(::before,::after) doesn't work?
Learn why the :is() selector doesn't work with pseudo-elements.
postcss-clampwind - Bring the power of clamp() to your utility classes
A Post CSS plugin that generates fluid, responsive CSS using the clamp()
function, without making you touch the math behind it.
Integrating CSS Cascade Layers To An Existing Project
You can always get a fantastic overview of things in Stephenie Eckles’ article, “Getting Started With CSS Cascade Layers”. But let’s talk about the experience of integrating cascade layers into real-world code, the good, the bad, and the spaghetti.
A Responsive Item Counter with CSS only
Learn to create dynamic "+X more" counters that update automatically without JavaScript, using CSS Container Queries, Custom Properties, and Counters for responsive components that adapt to container width.
CSS boilerplate
This boilerplate uses a reset stylesheet and comes with pre-defined rules, but primarily, it establishes a structure using Cascade Layers, giving you more control over the cascade.
Targetting specific characters with CSS rules
You can't. There is no way to use CSS to apply a style to every letter "E". It simply can't be done.
At least, that's what they want you to think…
What if I told you there was a secret and forbidden way to target specific characters in text and apply some styles to them?
Liquid Glass in the Browser: Refraction with CSS and SVG
Explore how to recreate Apple's stunning Liquid Glass effect using CSS, SVG Displacement Maps, and refraction calculations.
CSS Shapes using corner-shape
Ready for the new corner-shape
property? It allows you to manipulate the shape of the corners, and by simply adjusting the border-radius
, you can create most of the common CSS shapes.
What You Need to Know about Modern CSS (2025 Edition)
We published an edition of What You Need To Know about Modern CSS last year (2024), and for a while I really wasn’t sure if only a year later we’d have enough stuff to warrant and new yearly version. But time, and CSS, have rolled forward, and guess what? There is more this year than there was last.
One corner, two border radii
Did you know you can control the border radius of both sides of a corner indepenently of one another? It might seem a little strange to do, but you can do some intersting things with it.
HTML
Frontend complexity and the HTML renaissance
It feels like frontend development has become both simpler and more complex at the same time. JavaScript has swallowed the whole of frontend development, yet the newfound power of HTML and CSS has made JS entirely unnecessary for a great many tasks (lazy loading images, masonry layout, anchor positioning, scroll-driven animation…) Developers are approaching rendering simple UI components as if they were tackling a hardcore software engineering problem with the building blocks of the web increasingly abstracted into a Rube Goldberg machine.
Abstracting away HTML has meant there’s a whole generation of developers where basic knowledge of the most fundamental language of the web is often lacking. All because the default HTML elements are slightly too ugly and difficult to customise with CSS. HTML is mostly idiot-proof for anybody that can be bothered to learn it. The same can’t always be said for the miscellaneous dependencies and over-engineered abstractions that have defined the last decade.
Your Images Are (Probably) Oversized
Are you setting the sizes attribute on your <img/>
tags?
No?
Then you're most certainly serving images that are larger than they should be. Even for large-width (e.g. desktop) screens.
JavaScript
How React Works Behind the Scenes
Ever wondered how React works behind the scenes? Discover how React actually operates. Learn how JSX turns into real UI, what the Virtual DOM and Fiber Tree are, how reconciliation works, and how React updates your app efficiently.
Advanced App Router Routing Patterns (Next.js)
The App Router is more than nested folders. Here are lesser-known patterns I use in real projects to compose UX, keep code maintainable, and ship fast.
Use these as bite-sized recipes; each has a minimal example you can paste into a new Next.js app (App Router enabled).
SemanticFinder - Frontend-only Semantic Search with transformers.js
Semantic search right in your browser. Calculates the embeddings and cosine similarity client-side without server-side inferencing. Your data is private and stays in your browser. Just copy & paste any text in the text area or load one more PDFs & web pages in the advanced settings and hit Find. Set a different chunk size for finer or coarser search. Large books can be indexed too and searched in less than 2 seconds.
Stop using .reverse().find(): meet findLast()
Learn how Array.prototype.findLast()
and findLastIndex()
let you search JavaScript arrays from the end—no .reverse()
required. Cleaner, safer, and perfect for UI logic.
Miscellaneous
Web Interface Guidelines
Interfaces succeed because of hundreds of choices. This is a living, non-exhaustive list of those decisions. Most guidelines are framework-agnostic, some specific to React/Next.js.