Believe it or not, I don’t only work on or write about SQLite, and today I want to share a simple pattern for role management in Rails inspired by the rolify gem . I have been using this setup in the Rails app I am currently working on, and it has been a lovely experience. I’ve also had to evolve the pattern a bit recently, so I thought now was a great time to share the current state of things.…
Building HTML UI forced me to figure out how to write reusable CSS classes that play nice with Tailwind. Along the way, I looked at how other libraries tackle this. Spoiler: most of them get it wrong. Let me show you two approaches I found, then I’ll show you what I landed on. Here’s how Basecoat defines a badge: @layer components { .badge, .badge-primary, .badge-secondary, .badge-destructive,…
On September 23rd, 2025, in a Berlin hospital room, I became a dad. Emma Elanor Margheim entered the world and promptly rearranged every priority I thought I had. She’s currently asleep, so let me tell you about the rest of the year. Becoming a Family The year began with a milestone: on January 13th, Geniya became a German citizen. After oodles of paperwork and appointments and waiting, she walked…
I spent way too long getting the animations right for my dialog post . Chrome’s documentation on entry/exit animations made it look simple—define your open state, your starting state, your closed state. Three blocks of CSS. Done. The entry animation worked immediately. The exit was a disaster. The dialog snapped to full width mid-animation, jumped around, then vanished. The backdrop lingered after…
Campsite has some of my favorite UI styling on the web. Naturally, I cracked open their source hoping to learn something. What I found: React components rendering <div> s inside <div> s, with piles of JavaScript doing what <dialog> does for free. So I borrowed their visual design and rebuilt it with semantic HTML and CSS using affordance classes . I want to walk you through all of the choices I’ve…
Turbo’s data-turbo-confirm attribute is convenient for quick confirmation dialogs, but the native confirm() prompt it triggers looks dated and out of place. If you want a styled confirmation dialog that matches your app’s design, the traditional approach recommends a lot of JavaScript—a Stimulus controller to open and close the dialog, event listeners for keyboard handling, and coordination…
I was building a form with a file input. Nothing fancy—just a place for users to upload a document. I wanted the trigger to look like the other buttons on the page: the same subtle shadows, the same hover effects, the same spacing. I was using Catalyst , the component kit from Tailwind Labs, so I had a <Button> component with all those styles baked in. But I couldn’t use it. A file input needs a…
After some experimentation, research, and AI being stupid, I finally have a simple, clean implementation of a star rating component that uses only radio inputs and labels and allows for half steps. 50 lines of beautiful CSS. Let’s break it down piece by piece. Before I dove into the code, I did some research on how others had tackled this problem with pure CSS. I found two implementations that I…
I spent a bit of time this morning make some improvements to sqlite.directory , and I found myself needing to make a number of fixes around the mobile responsiveness of the UI. So, I thought I would take a moment to catalog a few common patterns and tips I have found useful when working with responsive design. This first tip was one that I found myself using quite a bit today. I use flex…
After the initial launch of sqlite.directory , I have been working on a few updates to the site. Here are some of the updates: Show count of apps ( 59ba725 ) Show favicon of app ( d89dfbe ) Randomize the order of app entries ( d703bf9 ) Validate that even the optional Repository URL is a valid URL ( 15ad911 Make the application more responsive ( 07a5a3d , ea01025 , e370f9d , daed3ab , 5568fdd ,…