Want to know when I publish new content?

Enter your email to join my free newsletter:

Articles and Tutorials

The One Media Query I Still Use

Container queries did not retire the viewport. They just stopped it from running the whole show.

Container queries ate a lot of my old breakpoint soup. I still keep one rem-based media query around, and it is the one that decides whether the page is a single column or a real layout. Here is why that split still belongs to the viewport.

Read more : The One Media Query I Still Use
Sixty Frames of Honesty

Profiling animation jank on a mid-range Android phone

A laptop will lie to you about motion. I started testing every enter animation on a mid-range Android phone, and a lot of my favorite CSS suddenly looked like a slideshow. Here is the checklist I now run before I ship a transition.

Read more : Sixty Frames of Honesty
Dark Mode Without the Flash

First paint should match the theme the reader already chose.

A theme toggle is easy. A first paint that does not blink white is the actual product. This is the small script I run before the CSS, the cookie I keep, and the one mistake that still causes a flash if you put the class on the wrong node.

Read more : Dark Mode Without the Flash
Buttons That Push Back

A press state should feel like a finger, not like a hover that got louder.

Hover is a desktop rumor. Press is the real event. I have been replacing hover-only button motion with a short squash on :active, and the UI immediately feels more physical. Here is the CSS, and the part you should not animate.

Read more : Buttons That Push Back
Grid for the Awkward Page

Flexbox kept wrapping the wrong thing. Grid made the page honest.

I spent a week forcing a homepage into flexbox because I already knew flexbox. The sidebar jumped, the popular list sat too high, and the sticky header had nothing to stick against. Switching the page shell to grid was not fancy. It was the layout admitting what it always was.

Read more : Grid for the Awkward Page
The Form That Does Not Lie

Client checks should say the same thing the server would say.

A newsletter field that accepts “asdf” and then dies on the server is not validation. It is a shrug. I started writing the browser check as a copy of the server rule, including the error sentence, so the page never invents a second opinion.

Read more : The Form That Does Not Lie
Filters for People Who Hate SVG

You do not need to love path syntax to use a filter well.

I used to treat SVG as a file the designer exported. Then I needed a gooey menu and a noise overlay that did not ship a PNG. A couple of filter primitives got me there without becoming an Illustrator person. This is the short list I actually reuse.

Read more : Filters for People Who Hate SVG
Shipping the Unpretty Version

The first public UI should look a little unfinished on purpose.

I used to hold a page until the mascot, the sounds, and the footer hills were perfect. Nobody saw it, so nobody told me the search was broken. Now I ship a plain version that already does the job, then I dress it. Taste comes after use.

Read more : Shipping the Unpretty Version