I am a software engineer by trade. So this of course means that I read a lot about development and it is typically a core topic of this blog.

One of the most devestating losses of the slow death of CSS Tricks is the loss of detailed guides for new, complex CSS features like Grid and Flexbox. It’s great to see the return of the personal blog where people like Ahmad Shadeed makes a great guide to :has like the one below.

Read CSS :has() Interactive Guide here

The browsers are warring again uniting to pound out some new features and bug fixes again. Y’all, I’m glad we are past the browser wars of ol’. Andy Bell has a great write-up on the focus of Interop 2024, a united effort to make things better for developers by having parity between all browsers.

Give it a read on Piccalilli!

Can I :has?

Firefox finally shipped :has in December, which means we can start shipping it in our code. Obviously depending on your users and you probably should consider backwards compatibility and such. But we are going to look at :has optimistically this morning.

So below is a navigation bar like what I use in Selah. You have a selected button and hover states. But the complex part is that the sharps (#) visually select their corresponding whole note button. In the past, this would be complex. You’d need to set a selected state in either a data attribute (e.g. data-selected) or a class as well as the aria-selected on both buttons. Not hard for JS, but more work.

And that brings us to :has. This is a pseudoclass that allows you to match elements on other elements. For instance, if I wanted to select an element with a focused input, I could do this:

.fieldset:has(input:focus) {
    border: 1px solid red;

We can look ahead, to pull a term from regular expressions. Onto our navigation bar, we want to show the selected state on a whole-note that is followed by a selected half-note.

.whole-note:has(+ .half-note[aria-selected="true"]) button {}

And we can also do this with :hover selectors, meaning we can say on hover of our half-note, we can show the hover state on the corresponding whole-note.

.whole-note:has(+ li.half-note button:hover) button {}

This is saying:

  1. Get the .whole-note.
  2. Check that it is followed by hovered half-note (:has(+ li.half-note button:hover)).
  3. And get the button for this match.

This changes everything. That’s only a slight exaggeration. Your code is more readable and more concise. You are shipping less code too.

Go, dabble and learn, y’all.

Andy’s following through on his promise to revive Piccalilli this year, publishing a great and thorough tutorial on making a switch component with modern CSS techniques, including :has and container queries. You really should subscribe to his blog if you are in the frontend space.

A highly configurable switch component using modern CSS techniques

The other day I added the ability to add Scripture metadata to Finley, I am. Then I went through all my articles from almost a decade and added the metadata. But I am a developer, so I didn’t just look through 500+ articles for references and add them, I made a quick regular expression to find them.

([1-3] )?[a-zA-Z]+ [0-9]+:[0-9]+(-[0-9]+)?

Even us old guys that have been working in CSS since the start… Scratch that. Especially us old guys that have been working in CSS since the start, we all need to read through this quick article and see some of the newer things in CSS that can make your code better.

I’ve been using aspect-ratio and margin-inline quite a bit over the last year on projects. I show my age, but so many things that we can now do easily in CSS— vertical centering…— used to take way too much code. Layout through grid and flexbox compared to old school floats is a marvel.

Go read Stephanie Eckles piece.

CSS Custom Properties are super powerful. Unfortunately a lot of people are still using them like Sass variables, forgetting that they are scopable and can do some pretty advanced things. This video walks through some cool methodology for making extendable components with a styling API.

Subgrid Changes Everything

For the frontenders out there, you’ve likely seen the news. Subgrid has shipped. It came to Firefox back in 2019, to Safari last year, and now Chrome has shipped it. If you haven’t been following, let me catch you up.


I got my starts in web development back around the turn of the century. Which was not that long ago. Promise. In those *barf* 20+ years, I have seen every major shift in how we lay out websites. When I started, we used tables still. It was gross, but we had no choice.

See the Pen Table Layout by James Finley (@thefinley) on CodePen.

For a table-based layout, you would start with a table to lay out your columns and rows and then nest child tables until you died in a nest of unmanagable code so you could get close to a complex layout. Luckily we never even considered people being on small screens back then.


At the end of the 1900’s— I just made a lot of people hate me— we got CSS and were told that it was for styling and format, while HTML was for semantics— describing the text and content of our page. Fair, but it had no true layout system. The closest it had was floats, which were really meant to allow you to have text wrap around an image. But we wanted a 6 column layout. So grid systems like and Bootstrap were born to allow us to use utility classes to layout pages. Along with that, we entered an era where vertical was problematic— having all your columns match height in a row required very gross tricks. Oh, and clearfixes. Look it up if you need a refresher.

But, our HTML became a lot cleaner as we got to write less code and allow CSS to do it’s thing.

See the Pen Float Layout by James Finley (@thefinley) on CodePen.


For most of the 2000’s we got used to laying out pages using grid systems built on floats. At the end of the 2000’s, we got our next big shift: flex box. And right in time for the Responsive Web movement. Chrome rolled out support in 2010, Safari in 2008, Firefox in 2006. IE got it with version 10 in 2012, which truly opened us up to use it.

See the Pen Flexbox Layout by James Finley (@thefinley) on CodePen.

Flexbox getting solid support and version usage by 2013-2015 meant we could finally easily center things vertically and horizontally for the first time since tables. Over a decade of CSS and no real layout system, no we had one, but we also had grid right on the horizon.


IE was first to implement Grid in 2015 to the surprise of everyone. This was when Microsoft really started to show signs of caring for web developers and supporting standards with Edge 12. Where flexbox worked well for layout elements out in one dimension— either column or row— grid was a real, true two-dimensional grid system built right into CSS. March 2017 grid shipped in Chrome, Firefox, and Safari. All at once within weeks of each other.

See the Pen Grid Layout by James Finley (@thefinley) on CodePen.

Instead of needing complex utility functions that did math, we now could tell a cell in a grid to start at column 1 and span 3 columns. And this has been are last 6 years of web development. I’ve been in this game for 20 years. Grid is a beautiful thing.



The original spec, from my understanding, included something called subgrid and it was dropped from the original release. You see in the demo above of grid, the grid can only be used by direct children of the element with display: grid. For grandchildren, they are out of luck. Remember us nesting tables back in the 1900’s? Yeah, we had to go back to that. You have a six-column layout with a cell taking up four columns of that. You want to have four items inside that each take up one column? Yeah, those items don’t know about the grid, so you have to establish a four-column grid on their parent and use the calc function to mastery to get your gaps to align. Subgrid was supposed to allow you to pass the grid onto the children of a grid cell.

And now we are caught up to the present. Subgrid has shipped. Browser usage stats are going up. The demo below will work in anything after Chrome 117, Safari 16, and Firefox 17. Edge will get it soon, from my understanding.

See the Pen Subgrid Layout by James Finley (@thefinley) on CodePen.

Now we can truly lay out pages where everything sits in one grid. Blocks on the page can be logically and semantically separated while not making layout complicated and can still internally rely on one grid.

See the Pen Complex Subgrid Layout by James Finley (@thefinley) on CodePen.

Each of these major eras of web layout have changed the way we think, the amount of code we write, and what designers are able to design. During the float era having three equal height columns was a PITA. Vertically centering something was too. Grid allows some truly complicated layouts that we are still not scratching the surface on, but in many ways it was hampered by the lack of subgrid support for the last six years. Subgrid changes everything once again and I am more than excited for this new era in web layout design.

Really impressive demo. First, this is for single-page applications. Second, there is an API for multi-page applications. Check it out in Chrome Canary and look at the code. I discussed this with my team yesterday. The demo is built on Astro. All that is shipped to the browser is 301kB. Of that 291kB is images. Less than 5.5kB for the document, CSS, and JS. CSS is powering the transitions and only a bit of JS intercepts the navigation event, loads the fragment of HTML, injects it into the DOM, and adds the necessary classes to trigger the animations.

This is a truly impressive demonstration. With very minimal effort, one can use an SSG like Astro— which can run as an SSR too— and deliver a fully working application that requires no JavaScript but progressively enhances to dynamic page transitions with easy— something that is extremely difficult even for SPA libraries— and asynchronous page loading. Only 150 lines of JS are in this project— 150 lines that ship to the browser.

For an old curmudgeonly standards guy like myself, this gives me some hope that we can get back to the days of the largest assets we send to the browser are images instead of hundreds of kilobytes of JavaScript.

Source: Bramus

Something non-designers understandably struggle with is how to make things look good. One of those things is long form content that’s well set and readable. Luckily, CSS makes this easy, you just have to know what to change. That’s exactly what we’re going to teach you in this article.

Set Studio

So many good tips in this article from Andy Bell. I’m using many of them already on this site. Long-form content can be hard to format, so if you need some help, tap the link above!