Accessibility
Why I Don’t Call Myself an Accessibility Expert
I’ve been working in the fields of disability inclusion and digital accessibility for over two decades. I’ve filed thousands of bugs. I’ve led accessibility programs at major tech companies. I’ve served on standards committees. I’ve written hundreds of articles and spoken at dozens of conferences. I have three disabilities myself.
And yet, I don’t call myself an accessibility expert.
The word “expert” carries weight. It suggests completeness and the end of a journey, where you have arrived at a destination where you know what needs to be known. The mismatch is that accessibility isn’t a destination. It’s a moving target being shot at by someone who’s also running.
Live Region Support
This post does not discuss whether live regions are good, nor is it a post about the best way to use them. This post only covers how they are exposed to the audience who experiences them — screen reader users. Written by a non-screen-reader user.
If you’re here because your live region isn’t working as you expect, then your expectation is wrong, you did something wrong, or you found a fun bug. Read Pat’s Why are my live regions not working? instead of this post.
CSS
Focus rings with nested contrast-color()?
As I was playing around with contrast-color(), I got a wild idea that you could use contrast-color() to invert its return value by nesting it: contrast-color(contrast-color(var(--some-color)). When would this be useful? Uh… Good question. I couldn’t come up with an example right away but after a bit I found one sitting right under my nose….
Drawing Connections with CSS Anchor Positioning
Every now and then, CSS gets a new feature that makes you pause and think: wait… we can do that now? That was exactly my reaction after watching a short by Kevin Powell on CSS Anchor Positioning.
The idea is deceptively simple: let one element position itself relative to another, without JavaScript, without fragile DOM assumptions, and without extra wrapper elements. Naturally, I had to try it myself.
What started as a small experiment turned into a neat little demo that visually connects a comment to its reply using nothing but CSS.
Radio button and checkbox styling: Vanilla CSS vs Tailwind
In this guide, we cover the basics of styling radio buttons and checkboxes, demonstrating how to:
- Make basic color changes using the simple
accent-colormethod (which hopefully more browsers will support in the not-too-distant future) - Implement a full style reset using
appearance: nonefor complete control
We also show you how to perform both methods using either vanilla CSS or Tailwind, the popular utility-first CSS framework that lets you style with predefined classes.
Solving Shrinkwrap: New Experimental Technique
In this article, I present my new technique for solving a CSS problem that was deemed impossible — true shrinkwrapping of an element with auto-wrapped content. By using anchor positioning and scroll-driven animations, we can adjust our element’s outer dimensions by measuring its inner contents, demonstrating that for many cases this can already work and might unlock a future native feature.
Elastic/Bouncy Text Effect
Combining modern features such as shape(), sibling-index()/sibling-count(), linear(), etc., to create a funny elastic effect on hover. There is no text duplication, but you need a monospace font and a wrapper per letter.
Nice Select
Building a modern custom select leveraging new CSS features like appearance: base-select, CSS anchor positioning, scroll-state queries, and animated transitions to create a custom dropdown that still retains native accessibility, keyboard navigation, and performance. The design includes advanced theming (light/dark modes, color mixing), smooth animations, touch and RTL support, and flexible layout options. JavaScript is used primarily to calculate positioning, while CSS handles most of the visuals and interactions.
Chrome-only at the moment, demo here.
Better defaults for popovers
I recently added a rule to my reset style sheet UA+ that I wanted to share with you.
When you add a popover to a page and open it, it looks similar to a dialog in terms of its styling. It's positioned at the center of the viewport. That's okay, but I would argue that in most cases you want your popovers aligned closely with the button that controls them. As it turns out, that's super easy to achieve in browsers that support CSS anchor positioning, since popovers already have an implicit anchor.
JavaScript
Angular RFC: Setting OnPush as the default Change Detection Strategy
Using OnPush has long been considered an Angular best practice, and developers have been requesting that we make this change for some time. Having best practices as the default means that developers and teams will not be required to take the additional opt-in step for every component. We believe now that zoneless is stable and well supported across the ecosystem, the time is right. Zoneless is the present and future of Angular applications, and changing the default ChangeDetectionStrategy is aligned with this reality.
We are targeting these changes for Angular v22 in May 2026. While we don't expect this to have any significant impact on your codebases, we're eager to hear what you think and to learn of anything we may have missed.
Introducing LibPDF: The PDF Library TypeScript Deserves
LibPDF is a new open-source PDF library built for TypeScript to fill gaps in the existing JavaScript/TypeScript PDF ecosystem, aiming to handle real-world PDF workflows more reliably than alternatives.
It was created because existing tools (like pdf.js, pdf-lib, and pdfkit) either focus on rendering, lack comprehensive parsing, or don’t support features needed for complex document workflows.
LibPDF’s features include lenient parsing, incremental saves that preserve signatures, native digital signatures (PAdES), encryption, form filling & flattening, text extraction, merge/split, font embedding, and more — all with a TypeScript-first API.
LibPDF - The PDF library TypeScript deserves
Parse, modify, sign, and generate PDFs with a modern TypeScript API. The only library with incremental saves that preserve digital signatures.
WarperGrid - Professional React Data Grid
A feature-rich React data grid with TypeScript support, modular plugins, and beautiful UI. Handle 10M+ rows with ease.
The OpenScriptJs Framework - Progressive, Lightweight JavaScript Frontend Framework for Artisans
OpenScriptJs is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. OpenScript attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as simple routing, powerful state management, and decoupled event handling.
It combines the best concepts from sophisticated backend architectures—like Inversion of Control (IoC) and Mediator Patterns—with the modern reactivity of frontend development. The result is a lightweight, zero-dependency framework that scales from small widgets to complex Single Page Applications without the bloat.
Yet another vanilla JS table library
YATL is a powerful, feature-rich, and lightweight Web Component data table built with Lit. It handles large datasets with ease using virtual scrolling, offers advanced fuzzy search capabilities, supports state persistence, and works in any framework (React, Vue, Angular, or Vanilla JS).
I needed a free and simple table library for vanilla JS that was easy to customize and could handle large datasets... so I created YATL. As the project that I wrote this for grew, so did this library. Now it is a web component built using Lit that is fairly feature rich for simple use cases. There are many other great table libraries out there but if you want something simple to just drop in but with all of the major features already included, YATL might be for you.
Features:
- Virtual Scrolling: Render 100,000+ rows smoothly with virtual scrolling.
- Smart Search: Tokenized fuzzy search with relevance scoring and highlighting.
- State Persistence: Automatically save and restore column order, visibility, sort, and widths to LocalStorage.
- Highly Customizable: Slot support, CSS Shadow Parts, and custom cell renderers.
- Interactive: Drag-and-drop column reordering, multi-column sorting (
SHIFT+CLICK), and resizeable headers. - Export: Built-in CSV export for visible or all data.
- Type Safe: Generic component with full type hint support.
Demo here.
Common Sense Refactoring of a Messy React Component
One thing I’ve learned from all the consulting I’ve done is that rewrites rarely lead to anything good. Almost in all cases, when you have an application running in production it’s better to put it in order rather than put it to the torch.
I’ve been given some chaotic codebases to fix throughout the years, though, and I wanted to show you my approach to tidying them up. In this article, we’ll go over a messy component that I had to refactor during an audit and how I did it.
JSBooks: A Curated List of Best Javascript Books
A curated list of the best JavaScript books (JS books) — free and paid — for beginners through advanced developers. If you’re searching for top JavaScript books, best JS books, or simply great JavaScript programming books to level up, start here.
jQuery UI 1.14.2 released
Believe it or not, jQuery UI 1.14.2 has been released. Of note:
"Please remember jQuery UI is in a maintenance state: we’ll make sure the library is compatible with new jQuery releases and that security issues are fixed but no new significant feature work is planned."
UX
Combobox vs. Multiselect vs. Listbox: How To Choose The Right One
Combobox vs. Multi-Select vs. Listbox vs. Dual Listbox? How they are different, what purpose they serve, and how to choose the right one. Brought to you by Design Patterns For AI Interfaces, friendly video courses on UX and design patterns by Vitaly.