Accessibility
The Anatomy of an Accessible Text Field
Forms are complicated. Or rather, forms consist of so many parts that they're easy to get wrong. Talking from experience: the odds of a website with forms having accessibility issues are nearly guaranteed.
The text field specified here is your starting point. Take this and iterate on it for your own use cases. Improve and adjust when you are certain you need to deviate. Otherwise take this example as your accessible default.
Judging severity in accessibility issues
We tend to agree easily that all accessibility issues are important, but we also acknowledge out of necessity that some issues are more critical than others. What we don’t always agree on is how to judge severity.
I use a rubric for judging severity that’s based on three conditions: importance, ubiquity, and challenge.
ARIA roles can remove their children’s semantics
Unfortunately, many people slap ARIA attributes on elements without really understanding what they're doing. Adding role="menu" to navigation lists is one example that I see very often.
ARIA menus require to include elements with role="menuitem" or otherwise they're be empty.
CSS
CSS Grid Native Masonry Layout
Level 3 of the CSS grid layout specification includes a masonry value for grid-template-columns and grid-template-rows. This guide details what masonry layout is and how to use it.
Responsive and fluid typography with Baseline CSS features
Learn how to use Baseline CSS features to create typography that responds to the user with accessibility and developer ergonomics in mind.
A Generator for Random Wavy Dividers
Generate a fancy wavy divider with one line of code using clip-path: shape().
Handy web-based generator here.
HTML
You are not required to close your <p>, <li>, <img>, or <br> tags in HTML
There are a number of reasons it is good practice to do so (which I’ll get to later in this article), but it is not wrong or inherently bad practice not to do so with elements with optional end tags or elements without end tags (believe it or not, these exist — they’re called void elements). Browsers do not treat missing optional end tags as errors that need to be recovered from.
It would seem that many authors who don’t know better have mistakenly believed that these rules carry over to HTML5 as they moved away from XHTML, and the misinformation has been spreading ever since.
HTML-only conditional lazy loading (via preload + media)
The accepted practice is to not add lazy-loading to images above the fold, especially the LCP image, since doing so can delay their loading until the browser has determined they are definitely in the viewport. One problem though is that "above the fold" depends on screen size: an image can be above the fold on desktop and below it on mobile. With native lazy loading and static HTML (e.g., without device detection on the server side or JavaScript), you normally have to pick one behavior and get it wrong for part of your users.
But there's a small workaround that seems to work. Browsers won't delay the loading of an image if it's already been fetched. You can take advantage of that by conditionally preloading the image using a media query, then marking the image as lazy later. I tested it using the HTTP link header, but may also work fine with a <link rel="preload"> tag.
A polyfill for the HTML switch element
In Safari 17.4, the WebKit team at Apple shipped a native HTML switch element. The core idea is that an <input type="checkbox"> can progressively be enhanced to become a switch by adding the switch attribute. Browsers that don't support the switch attribute will just silently ignore it and render the switch as a regular checkbox. At the time of this writing, Safari version 17.4 and later is the only browser to support the new switch element natively. This blog post introduces a polyfill that brings almost native support to browsers that lack it.
You can get the polyfill from npm and find the code on GitHub. The README has detailed usage instructions, including important tips on how to avoid FOUC (Flash of Unstyled Content). You can also play with a demo of the polyfill that shows off more features of the polyfill, like all the various writing modes, and the different ways to style the switch.
Optional HTML: Everything You Need to Know
What HTML code is optional? This article gives an overview over everything optional other than extraneous whitespace and anything standard minifiers already handle. There’s much to omit and omitting is good for us.
SVG Filters are just amazing!
SVG filters are a powerful way to apply graphical effects to SVG elements. They can also be applied to HTML elements using the filter CSS property. Without SVG filters, achieving complex visual effects like the water ripple effect would require using images or complex JavaScript animations.
Introducing the <geolocation> HTML element
From Chrome 144 you can use the new <geolocation> HTML element. This element represents a major shift in how sites request user location data—moving away from script-triggered permission prompts toward a declarative, user-action-oriented experience. It reduces the boilerplate code required to handle permission states and errors, and provides a stronger signal of user intent, which helps avoid browser interventions (like quiet blocks).
JavaScript
cards.js - Write card games in Javascript.
cards.js is a library to write card games in javascript. It's not a framework, it does not try to tell you how to write your game logic, it's only about rendering playing cards, animating them and giving you a nice and simple way to use them in your games.
GitHub repo here.
Absolutely everything you need to know about act() in React tests
When writing React tests, you will quickly become familiar with the act() function. Despite being a fundamental concept to testing your React apps, it is often one of the most confusing and misunderstood aspects of testing React applications.
I've also in the past found it hard to articulate why we need it to engineers learning how to test their React apps.
How to Steal Any React Component
Steal any component from a production React website without source code - using React Fiber and LLMs to reconstruct working components.
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript
The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.
This book is completely Free and Open Source.
Stop turning everything into arrays (and do less work instead)
Iterator helpers are chainable methods on iterator objects, not arrays.
That distinction matters: arrays don’t gain these methods directly. You need an iterator from values(), keys(), entries(), or a generator. Then you can build a lazy pipeline on top of it.
They let you do things like:
mapfiltertakedropflatMap*find,some,everyreducetoArray
Most of these helpers are lazy, meaning they only pull values as needed. In general, laziness means:
- No intermediate arrays
- No unnecessary work
- Computation stops as soon as it can
You describe what you want, and the runtime pulls values only when needed.
JS Shake Detection Tutorial - Learn how to detect device motion without any libraries
To detect a shake, we use the browser's devicemotion API. This tutorial covers the math, the iOS permission requirements, and the final implementation.
Date is out, Temporal is in
Temporal is the Date system we always wanted in JavaScript. It's extremely close to being available so Mat Marquis thought it would be a good idea to explain exactly what is better about this new JavaScript date system.
Temporal Playground - Learn the JavaScript Temporal API
Interactive playground with 16 curated examples to learn the Temporal API. Live code execution, comparison with Date, and TypeScript support.
How wrong can a JavaScript Date calculation go?
The Date object in JavaScript is frequently one that causes trouble. So much so, it is set to be replaced by Temporal soon. This is the story of an issue that I faced that will be much easier to handle once Temporal is more widespread.