☕ The Weekly Dev's Brew #25

☕ The Weekly Dev's Brew #25

Grab your favorite mug and settle in for this week's web development updates. Today we're diving into the CSS features that topped the charts in 2025's State of CSS survey - and trust me, once you see what :has() and subgrid can do, you'll wonder how we ever lived without them.

☕ The Main Pour: :has() and Subgrid - The Dynamic Duo We Didn't Know We Needed

The State of CSS 2025 results are in, and two features are stealing the show in ways that would make your morning espresso jealous. With 80.4% adoption, :has() has become the most-used new feature, while subgrid claimed the "most commented" award with developers practically writing love letters about it.

Full confession: I hadn't actually used either of these features until I saw these survey results. So I did what any curious developer would/could/should do - grabbed a fresh cup, opened into the docs, built some demos, and now I'm here to share what I learned. Turns out, we've all been missing out on some serious CSS magic, well, at least I have been!

The :has() Selector: Your CSS Just Got Superpowers

Remember all those times you wanted to style a parent element based on what's inside it? Let's get more specific. Think about a simple form. You want to give the user immediate visual feedback as they fill it out.

Normally, you'd reach for JavaScript to add or remove classes on the parent container. Not anymore. With :has(), you can style a form field's wrapper based on the state of the input inside it.

The Problem: You have a <div> wrapping a label and an input. You want the div's border to turn green when the user focuses on the input and enters valid data, and red if it's invalid.

The CSS Magic:

CSS

/* The container for our label and input */
.form-group {
  padding: 1rem;
  border: 2px solid #ccc;
  border-radius: 8px;
  transition: border-color 0.3s ease;
}

/* If the group HAS an input that is focused AND valid... */
.form-group:has(input:focus:valid) {
  border-color: lawngreen; /* ...make the border green! */
}

/* If the group HAS an input that is focused AND invalid... */
.form-group:has(input:focus:invalid) {
  border-color: #C0FFEE; /* ...make the border tasty! */
}

Now, the .form-group is smart. It "looks inside" itself and reacts to the state of its children in real-time. This is a massive improvement for creating interactive, intuitive forms and other components with zero JavaScript.

Subgrid: The Layout Feature That Makes Everything Line Up

If :has() is the espresso shot of CSS, subgrid is the perfectly steamed milk that creates flawless latte art. It solves one of the most frustrating problems in component-based layouts: keeping things aligned.

The Problem: You have a grid of three product cards. Each card has a header (product name), a body (image/description), and a footer (price/button). But uh-oh—one product has a longer name that wraps to a second line. This makes its header taller, pushing its image and button down and throwing the entire row of cards out of alignment. It looks unprofessional.

The CSS Magic: subgrid allows a child grid (your card) to inherit the grid tracks from its parent (the main page layout), forcing everything to line up perfectly.

CSS

/* 1. Define the main grid layout and its rows */
.card-grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  /* Define rows for header, body, and footer */
  grid-template-rows: auto 1fr auto;
  gap: 2rem;
}

/* 2. Each card opts into the parent's grid */
.card {
  display: grid;
  /* This is the key! The card's rows will now use the parent's row tracks */
  grid-template-rows: subgrid;
  /* Make the card span all 3 rows we defined in the parent */
  grid-row: span 3;
  
  /* Add some styling */
  border: 1px solid #eee;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}

/* 3. The card's children now align perfectly across the grid */
.card-header { grid-row: 1; } /* Always in the first row track */
.card-body   { grid-row: 2; } /* Always in the second (stretchy) row track */
.card-footer { grid-row: 3; } /* Always in the third row track */

The result is some fancy layout. The .card-grid-container defines the master rows for all headers, bodies, and footers. Each .card then uses subgrid to lock its children into that master grid. When one header grows, the entire "header row" across all cards grows with it, keeping the content and footers below perfectly aligned. This might finally be reason enough for me to ditch flex-layout and go all in on grid!

🚀 Quick Sips: Resources Worth Your Time

📦 Microfrontends Are Here (Vercel)

Vercel just dropped microfrontends support in public beta. Split your monolithic apps into smaller, independently deployable pieces. Build times go down, team velocity goes up, or so they say…

🧩 React Hooks Deep Dive (Playful Programming)

Ever wondered how React Hooks actually work under the hood? This interactive guide shows you how to build them from scratch, revealing the linked-list magic that makes useState remember your values.

🎨 Better CSS Layouts (Ahmad Shadeed)

Ahmad's latest breaks down Time.com's hero section and rebuilds it with modern CSS. Container queries, :has(), grid areas - it's a masterclass in flexible, maintainable layouts.

💭 Lee Robinson's React Reflections

After 5 years managing the Next.js community, Lee shares candid thoughts on React's evolution, RSC adoption, and the challenges of open-source community management. Required reading for anyone in the React ecosystem and even remotely tangent.

🎙️ Fresh Podcast: Drizzle's "If You Know SQL, You Know Drizzle" Philosophy

This week's episode features Andrii Sherman, co-founder of Drizzle ORM, breaking down their approach to database tooling. Key takeaways:

  • The Headless ORM concept: Why Drizzle doesn't try to hide SQL from you

  • Smart migrations that actually understand your schema changes

  • Building a sustainable 20-person team around open source

  • Working from Ukraine during wartime

The philosophy is refreshing: instead of abstracting SQL away, Drizzle enhances it. It's like the difference between instant coffee and pour-over - both get you caffeine, but one respects the craft.

🎧 Watch on YouTube 

☕ Coffee Corner

This Week's Coffee Fact: The world's most expensive coffee, Kopi Luwak, involves beans that have been eaten and excreted by Asian palm civets. The digestive process supposedly gives it a smoother, less bitter taste. At $100-600 per pound, it's literally worth its weight in... well, not gold, but close. (Though many argue it's more marketing than magic - [insert snarky joke about JavaScript here 😏])

Stay caffeinated,

The Weekly Dev Brew Team

JOIN THE BREW CREW

Don't miss the next episode and stay up to date completely for free