Accessibility
There’s no need to include ‘navigation’ in your navigation labels
When you mark up your website, groups of links are probably going to be wrapped in <nav> elements. If you have more than one, you’re going to have to label each of them so that screen reader users know what each is for.
I talked about using aria-label to differentiate each <nav> group, but I didn’t really mention how to write your labels
The Accessibility Problem Isn't Design. It's Engineering
The European Accessibility Act came into force on 28 June 2025. Teams audited their components, ran Axe, added ARIA attributes, and ticked boxes. Compliance documents were written. Statements were published in footers. And then most of them moved on.
Nine months later, it’s worth asking what actually changed.
Accessibility isn’t a design problem with a checklist solution. It never was. The specs were written, the components annotated, the guidelines documented. And then engineering shipped something broken anyway. The design was right. The code wasn’t. It’s the same story on almost every team, in almost every organisation, repeated endlessly while the industry pretends the problem is about awareness.
It isn’t about awareness. It’s about who’s writing the front-end code, and whether they’re qualified to write it.
Quick Tip: Dialog Focus
The specifications for dialogs and modals recommend placing focus on the first focusable item in the dialog.
I strongly recommend that this is not the best practice we should be following. We should be providing the user with information they need in a way that encourages them to explore. To accomplish this, I recommend placing the focus on the heading of the dialog. We do this by providing a proper ID and tabindex="-1".
Tests for CSS generated content alternative text
Sometimes, designers use CSS content: to add text or icons before or after elements. If that content is meant to be seen, it might also need an accessible version for people who can’t see it.
The spec allows you to add alternative text by putting it after a slash in the content property. The part before the slash is what’s shown visually.
As per the CSS Generated Content Module Level 3 specification, the slash alternative text is intended as a replacement for speech output.
Accessible Modals: How to Build Dialogs That Don't Trap, Confuse, or Exclude Users
Most modal dialogs fail at least 3 WCAG criteria out of the box. Here's what goes wrong, why screen reader and keyboard users get locked out, and the exact HTML, ARIA, and JavaScript patterns that fix every issue.
Playwright Accessibility Testing: What axe and Lighthouse Miss
axe and Lighthouse miss 60–70% of WCAG violations. Learn the limitations of automated accessibility testing and how to write smarter Playwright tests.
AI-Generated UI Is Inaccessible by Default
This happens because most LLMs optimize for visual output while generating near-zero semantic information for the layer that assistive technologies actually read. This article explains the architectural reasons and presents a five-layer enforcement system of prompt constraints. These include static analysis, runtime testing, CI integration, and accessible component abstractions that make semantic correctness automatic rather than aspirational. The examples use React and Tailwind because that’s what most AI tools emit, but the accessibility tree doesn’t care about your framework. It cares about the DOM it receives.
box-shadow is no alternative to outline
People like to use the box-shadow property for styling focus outlines because it gives them more flexibility.
That's okay in browsers' default color mode, but in forced colors mode, it's problematic because the box-shadow property computes to none, which means that there are no shadows and consequently no focus styles in this mode.
CSS
Inverted themes with light-dark()
We rolled out adaptive light-dark() support on our design system themes and it’s been a delightful upgrade. Creating light and dark variable sets isn’t difficult, but delivery has trade-offs. Most apps that do this probably ship both sets of token values in a single stylesheet. That’s fine until you have multiple kilobytes of duplicate definitions. To get around the performance problems we built two separate stylesheets –which is also not great– but my coworker Zacky found a good trick with <link disabled> to make it tolerable. Ultimately, we wanted to offer a single stylesheet for our human (and agent) friends to control theming.
Convert Complex SVG Shapes into CSS
I updated the SVG-to-CSS converter to support multiple path elements rather than just a single path. Now, you can easily convert complex SVG shapes into CSS.
You will get a responsive code created using a single element and a single shape() function. You can also have the border-only version using border-shape.
Squash and Stretch
Explains “squash and stretch,” a core animation principle that makes motion feel more natural and lively by slightly deforming objects as they move. Using examples like a bouncing ball and interactive SVG arrows, it shows how elements can compress (“squash”) on impact and elongate (“stretch”) during motion to convey elasticity, speed, and weight.
This focuses on practical web animation techniques—demonstrating how to implement these effects with CSS or JavaScript libraries, emphasizing subtlety, accessibility (like reduced-motion preferences), and polish (spring physics). Overall, the key idea is that small, well-crafted deformations can dramatically improve the feel and personality of UI animations without adding much complexity.
The Radio State Machine
Managing state in CSS is not exactly the most obvious thing in the world, and to be honest, it is not always the best choice either. If an interaction carries business logic, needs persistence, depends on data, or has to coordinate multiple moving parts, JavaScript is usually the right tool for the job.
That said, not every kind of state deserves a trip through JavaScript.
Sometimes we are dealing with purely visual UI state: whether a panel is open, an icon changed its appearance, a card is flipped, or whether a decorative part of the interface should move from one visual mode to another.
In cases like these, keeping the logic in CSS can be not just possible, but preferable. It keeps the behavior close to the presentation layer, reduces JavaScript overhead, and often leads to surprisingly elegant solutions.
7 View Transitions Recipes to Try
View transitions are really, really neat. I’m sure you’re like me and have come across more than a few in the wild that both make you go wow and want to instantly use them on your own site or project.
I tend to find that the best way to learn something new is to see the code, use them myself, and then build upon them. So, I’ve collected seven view transition recipes for exactly that. We’ll go over the basic setup and demo the recipes.
Article also links at the bottom to a bunch of view transition examples in an interactive demo that are definitely worth a look.
IE Page Transitions
Bringing back Internet Explorer’s Page Transitions thanks to the View Transition API.
Your “Tiny” CSS Animation Might Be Burning CPU 24/7
My dashboard sat at 10–15% CPU nonstop. The culprit was a harmless-looking "loading dots" animation.
I replaced it with plain … CPU dropped to ~0-1%.
The animation added zero real value but cost real CPU the entire time the page was open.
Letting Product Teams Own SVG Icons (Without Code Changes)
Step 1: host SVGs on S3
The first part is straightforward: upload the SVG files to an S3 bucket with public access. This gives product teams a simple upload interface to swap icons anytime they want.
Step 2: color them dynamically with mask-image
Here's the smart bit: instead of loading the SVG as an <img> (which can't be styled) or inlining it (which couples it to the codebase), we use the CSS mask-image directive.
mask-image lets you use an image (including an SVG) as a transparency mask over an element. Only the shape of the SVG is visible, you control the fill via background-color.
Since we set that to currentColor, the icon inherits the color of its surrounding context automatically.
Building a UI Without Breakpoints
While breakpoints were an excellent answer to a real problem when multiple screen sizes emerged, modern interfaces are no longer page-first. They are component-first, nested, and reused across wildly different contexts. In that world, global viewport width is frequently the wrong input for local layout decisions.
This article proposes a different approach, one that better fits the modern web: build fluid, intrinsic components that adapt by default, and treat conditional rules as local, intentional exceptions.
Container Query Typography Systems
With the adoption of container queries in all browsers, it's time to use them to fix typography systems.
HTML
SVG Filters Guide: Getting Started with the Basics
Since I’ve started posting SVG filter demos, people often ask me how to get started in this area. While I firmly believe the best way is to just start using SVG filters, I’d also like to provide this starter’s guide, the stuff I wish I had read while getting into all this.
JavaScript
scroll-into-view-promise — Promise-based scrollIntoView for the web
The native scrollIntoView({ behavior: 'smooth' }) has no callback. You can't know when it finishes. This tiny wrapper returns a Promise that resolves when the scroll is done.
Fresh Release of SVAR Vue UI Components
After building production-ready component libraries for Svelte and React, we’re excited to announce the release of SVAR components for Vue 3.
The release includes free, open-source components for building interactive web interfaces:
- SVAR Vue Core - UI library of 30+ components for data-driven interfaces
- SVAR Vue Editor - Configurable edit forms for any structured data
- SVAR Vue Filter - A complete filtering toolkit, from compact bars to query builders and YouTrack-like inputs with natural language search
All three are Vue-native, TypeScript-ready, and built to work together or independently, depending on what your project needs.
The components are open-source and free-to-use under the MIT license. You can find them on our GitHub page.
Patterns.dev Skills
Agent Skills for JavaScript, React, and Vue development. From patterns.dev.
58 individual skills. Install only the patterns you need.
Creating Custom Page Transitions in Astro with Barba.js and GSAP
Follow along as we build page transitions in Astro with Barba.js and GSAP, from the initial setup to a working animated transition flow.
Demo here.
Gridstack.js | Build interactive dashboards in minutes
Mobile-friendly modern Typescript library for dashboard layout and creation. Making a drag-and-drop, multi-column responsive dashboard has never been easier. Has multiple bindings and works great with Angular (included), React, Vue, Knockout.js, Ember and others (see frameworks section).
Lots of demos here.
tiks — Procedural UI Sounds for the Web
Every native app has satisfying sounds — iOS toggle clicks, macOS trash crumple, Android keyboard taps. Web apps have nothing. tiks brings that missing sensory layer using the Web Audio API. Every sound is generated at runtime through oscillators, noise buffers, and gain envelopes. No audio files shipped. Just math.
All sounds share a common synthesis engine with a unified theme — so they sound like they belong together.
Miscellaneous
The New Designer/Developer Collaboration
There's lots of ways to build a website. Most of them involve designers working in one tool, developers working in another, and a painful handoff process somewhere in between. We recently used Intent to build and ship a well-crafted website in about three weeks, and the collaboration model that emerged shined a light on how things could (no, should) be.
The biggest win was that any one of us could contribute meaningfully to the codebase without breaking the design system, code structure, or the site. That's a fundamentally different dynamic than waiting for a developer to make every change.
Subsetting Fontawesome to save 250KB
How to subset Font Awesome, meaning you only include the icons your site actually uses instead of the full library. This dramatically reduces file size and improves load performance, since Font Awesome includes thousands of unused icons by default.