Daily Tips I finally got a chance to work with the :has() CSS pseudo-class as part of Kelp, my UI library for people who love HTML. Today, I wanted to quickly look at what it is and how it works. Let’s dig in! If an element has a child or sibling, style the element CSS has long had all sorts of…
Daily Tips I’ve been full-steam ahead building a UI library for people who love HTML, powered by modern CSS and Web Components. I’ll be launching a proper website for it and more details in the next week or three, but today, I wanted to talk quickly about the set of utility classes it’s going to…
Owning your own data is hard. I've been trying to own as much as I can, and my site has become a reflection of that process, both in what I display and discuss. As difficult as it is, there's a freedom in owning as much as you can. When Twitter was sold, I joined the migration to Mastodon. I have my…
Text reflow on the web has an interesting relationship with Responsive Web Design. As a column gets smaller text wraps and becomes taller1. But for large format display text, that’s not always what you want2. What I’ve wanted for awhile now is a way to inversely size text based on the text length…
A friend shared this tip the other day and it was too useful not to reshare. If you’re a mobile-up kind of developer, it’s easy to forget that max-width media queries are “less than or equal to” by default. It can play havoc with your nice round numbers: If you want to tidy that up, and continue to…
Daily Tips Years ago, I was staunchly in the “minify your code, even if you use gzip” camp. But these days, I’ve switched teams! I did some tests on the bundled version of Kelp UI. Unminifed: 58.2kb Minified: 43kb Unminified + gzipped: 8.2kb Minified + gzipped: 7.4kb I don’t think making your code…
Like ’em or loath ’em, whether you’re showing an alert, a message, or a newsletter signup, dialogue boxes draw attention to a particular piece of content without sending someone to a different page. In the past, dialogues relied on a mix of divisions, ARIA, and JavaScript. But the HTML dialog…
So I’m making a thing and I want it to be styled different if the link’s been visited.
Rather than build something myself in JavaScript, I figure I’ll just hook into the browser’s mechanism for tracking if a link’s been visited (a sensible approach, if I do say so myself).
Why write JavaScript when…
I use Goatcounter for analytics primarily to see where things I post might get mentioned. I don't get a ton of traffic, nor should I expect to. However, checking the dashboard this morning, I saw that 82% of my traffic was now attributed to China. 89% of visits had no referrers, 85% using Windows…
Daily Tips I’ve been working hard on getting Kelp, my UI library for people who love HTML, ready to share publicly. A big part of the library design has been providing layout options that are flexible and give you a lot of options, without resulting classitis like you see in systems like Bootstrap…
Daily Tips On Monday, I shared how Kelp UI implements the container layout pattern. And yesterday, we learned about the cluster layout. Today, we’re going to look at another layout pattern in Kelp: the split. Let’s dig in! The split layout A split layout is when you have two elements in a section,…
If you write a lot of CSS, you are familiar with those moments when you aren’t quite sure how to accomplish what you want to accomplish. Usually, you’ll turn to tutorials or documentation, and learn more about CSS to get your work done. But every once in a while, you realize there is no “proper” way…
I mentioned last time that I’ve been working on a new website for Emmy-award-winning game composer Mike Worth. He hired me to create a highly graphical design that showcases his work. Mike loves ’90s animation, particularly Disney’s Duck Tales and other animated series. He challenged me to find a…
2 March 2025 Last week I posted a UX challenge on LinkedIn. I received 177 responses from senior designers and content designers. But the best response came from Joyce, a self-proclaimed non designer. The challenge was simple: === Which question label works best for ‘delivery’ and ‘collection’: ===…
I’ve been thinking about the kind of CSS I write by default when I start a new project. Some of it is habitual. I now use logical properties automatically. It took me a while to rewire my brain, but now seeing left or top in a style sheet looks wrong to me. When I mentioned this recently, I had some…
Daily Tips Back in March, I wrote about the :is() pseudo-class and how it can be used to reduce selector complexity. Today, I wanted to talk about another pseudo-class that does the same thing, :where(), how they’re different, and when to use one versus the other. Let’s dig in! How :where() works…
Subscribe Blog RSS feed Notes RSS feed or Combined and follow Mastodon Bluesky Thursday 8 Jan 2026 Play Synthesised Audio Shoutout to Robb Knight! I was struggling for time and a topic to kick-start the year. I don’t think the title is trademarked so I stole it :) Robb also has a /uses page. I…
I complained about this on the socials, but I didn’t get it all out of my system. So now I write a blog post. I’ve never liked the philosophy of “put an icon in every menu item by default”. Google Sheets, for example, does this. Go to “File” or “Edit” or “View” and you’ll see a menu with a list of…
Daily Tips Today, I wanted to share a little approach you can use to create accessible, HTML-native accordions (sort of), without any JavaScript. There are going to be included in the new UI library I’m building for people who love HTML, and I wanted to show you how they work. Let’s dig in! and …
Creating a strong project brief is one of the most valuable steps you can take to ensure your web design or development project runs smoothly. Whether you’re working with a freelancer or a full-service agency, a well-structured brief helps align expectations, avoid confusion, and keep everyone…
Daily Tips For years, JSHint has been my linter of choice. I like the defaults, and it basically works well out-of-the-box without any configuration. But I’ve had to use Typescript a lot more lately, and JSHint doesn’t work with it. In year’s past, I’ve used ESLint, but I kind of hate it. It just…
This post contains swear words. I’ve censored the first one, but read on at your peril! Many years ago, I had a client that sold a service. They weren’t a design agency, but for the sake of anonymity, we’ll just call them a design agency. Let us say that their core offering was a full-service design…
Published on: November 25, 2025 Last updated on: November 26, 2025 Categories: Current music: Mitski — Pearl Diver Current drink: Infusion of hibiscus, apples, rosehip, and orange peels, with cherry flavor. The title of this post might not seem like a big deal, but the problem I will talk about was…
7 December 2025Friendship ended with GitHub friendship-ended-with-github Since last year, this blog has been running on Hugo. For a while, I used a repository on GitHub that would build and deploy to GitHub Pages. Microsoft is currently targeted by the BDS campaign, which is enough of a reason to…
Daily Tips Today, I wanted to quickly share how I built Kelp’s toggle switch component with a single HTML attribute and CSS (no JavaScript required). Let’s dig in! The [role="switch"] attribute The [role="switch"] attribute is functionality identical to [role="checkbox"] (the implicit role a…
There’s the old adage “nobody gets fired for buying IBM”. Or to put it more broadly, “everyone else is doing it.” It’s dispiriting how often this explanation is given as justification for a dubious design decision, from home-page carousels to cookie banners. Nic Chan has written a great post about…
30 November 2025 I will answer this question, but it’s best explained by telling you about the post I wrote on LinkedIn last week: Github’s Design System has banned toast messages. Toast messages are little messages that appear on top of the UI to give you feedback about an action you just took.…
If you’ve ever needed to limit an element’s line count without resorting to JavaScript, the line-clamp CSS property can help. It’s a handy way to rein in user-created content, keep cards neatly aligned, or prevent text from breaking a layout. In simple terms, line-clamp limits the number of lines in…
Daily Tips Last week, I wrote about my experience working with the team at Cloud Four, and in particular some of their great practices around PR management. Today, I wanted to talk specifically about a habit my friend Gerardo Rodriguez got me into: reviewing your own pull request. It’s pretty…
No doubt this has been written about before, but I used this approach yesterday and it’s cool so I’m writing about it too. Like any good website, I have a pile of links in the footer of this one. Most of the links are to internal pages. A handful of them are to external sites. It’s never bothered me…
19 May 2024 Last week I posted this on LinkedIn: I tell my students to avoid select boxes. Because it’s often better to go for radios. But they often say “But it’ll make the page long”. Yep, but that doesn’t necessarily mean it’s bad UX. See below for the page I designed to let users select a…
Daily Tips One of the weirdest “debates” I seem to perpetually have with framework-enthusiastic developers is whether or not a is “just as good” as a . Spoiler: it’s not. Let’s dig in. The problem Among the React crowd, and also among people who seem to enjoy HTMX, I see a lot this… What’s wrong…
Daily Tips Something I’ve seeing more and more of with my clients is code that’s repeated in multiple places, but written in a way that it has to be manually duplicated every time. It’s particularly prevalent in JS-heavy apps. Let’s dig in! HTML Components Sometimes, it’s two UI components that do…
The year is 2005. You're blasting a pirated mp3 of "Feel Good Inc" and chugging vanilla coke while updating your website. It’s just a simple change, so you log on via FTP, edit your style.css file, hit save - and reload the page to see your changes live. Did that story resonate with you? Well then…
This is one of those cases where circumstances at my job led to needing to document expected behavior in order to create “synthetic” links via JavaScript. Sometimes this sort of thing is regrettably unavoidable. A large part of the effort was capturing all the different actions you can perform with…
UX design patents are elements that you can reuse and utilize to solve usability problems when designing the user experience of your website or app. Unlike UI patterns, they are not physical; instead, they are the ways through which you provide certain experiences or handle particular situations,…
oklch is a newer color model that is designed to be perceptually uniform. This means that colors are much more accurate in terms of how humans perceive them and it makes working with them much easier. Color Models Before being able to understand how oklch differs from the other color models, it is…
28 May 2023 My plugin for Markdown-It: CodeWrap Table of Contents I’ve just released a plugin for Markdown-It. I wanted to have tighter control over how my code blocks were displayed on my site, adding a "Copy" button as well. Maybe it’s over-engineered. Maybe it’s a niche need. But I certainly…
Friday 12 Sept 2025 Play Synthesised Audio CSS “resets” are boilerplate code designed to remove or normalize browser defaults. They provide solid foundation to build bespoke CSS upon. When utilised correctly they should be unobtrusive. Any quirks being ones of personal taste and flair. These quirks…
Daily Tips Today, I wanted to share how I built my own DIY Netlify that I use to host over a dozen sites for just $10/month, with way more control and much faster build times. Let’s dig in! The Netlify Revolution A few years back, Netlify helped usher in the era of static site generators by offering…
No articles.