1 Thing A Week 1 Thing
A Week

Why I can't wait for the :has() pseudo-class in CSS

Week 205.0 — 27th September '21

This past week I had a great idea for a tiny PWA that would only use JavaScript to make sure it worked offline and nothing more. In the future, I could make use of localStorage to remember preferences, but beyond that there would be no need at all.

I finally carved out some time after a few days mulling over the idea and was determined to make it work with the :has() pseudo-class but it turns out that browser support is non-existent! I've seen it talked about for at least a year, maybe more so had assumed it would be safe to use.

I came to the realisation yesterday that I should give up on the CSS-only approach, for now. I can revisit once browser support starts ramping up and strip out any JavaScript that's no longer required.

Why I can't wait for :has() to come to CSS

The reason I can't wait for the :has() pseudo-class is that it's effectively a parent selector for CSS. I've been working professionally with CSS since 2005 and it's something I've wanted for the past 16 years at least. In the days before heavy JavaScript pages where things were just progressively enhanced, adding classes dynamically as you created the HTML was easy enough – even if it meant more logic than was ideal.

Then came along jQuery with its .parent() function that meant we could progressively enhance the page rather than having to fetch from the server every time. In reality, this meant twice the logic in some cases. Once for the canonical server-side rendered pages and another for how it should be handled in JavaScript.

When we finally get our hands on :has(), no longer will we need helper classes or will we need to specify which item is 'active' at a higher level than the developer wants it to be.

Here's an example of some HTML and where our classes are required right now. We have a menu where a sub-item is selected which needs to be highlighted, but I'd also like to highlight the parent item it belongs too but that also means adding a class:

<div>
    <ul>
        <li><a href="#">Item 1</a></li>
        <li><a href="#" class="active">Item 2</a>
            <ul>
                <li><a href="#" class="active">Item 1</a></li>
                <li><a href="#">Item 2</a></li>
             </ul>
        </li>
        <li><a href="#">Item 3</a></li>
        <li><a href="#">Item 4</a></li>
        <li><a href="#">Item 5</a></li>
    </ul>
</div>

Once we get :has() in CSS though, our HTML changes a little and the parent no longer needs an explicit class to show that it's active:

<div>
    <ul>
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a>
            <ul>
                <li><a href="#" class="active">Item 1</a></li>
                <li><a href="#">Item 2</a></li>
             </ul>
        </li>
        <li><a href="#">Item 3</a></li>
        <li><a href="#">Item 4</a></li>
        <li><a href="#">Item 5</a></li>
    </ul>
</div>

With just some CSS, we can now do the following to determine that the 'parent' has a child that meets the criteria:

li:has(.active) > a {
    font-weight: bold;
}

It really would be that simple, now the parent of an element with the class "active" is targeted with its direct descendent styled.

I would personally prefer 'contains' or 'parent-of' instead of has for the pseudo-class name but I won't complain too much! This is yet another huge step in the right direction.

More from 1 Thing A Week
« Did you know you can send a SMS from HTML? Second linked data update: It worked! Can you change the animation-duration property in CSS smoothly? The and elements in HTML »

Advertisement

Notable

Quick links and commentary on interesting articles, videos and more throughout the week.

  1. 205.3 – Wednesday
    1. Lego versions of iconic album covers kottke.org
    2. Everrati Electric Porsche 911 blessthisstuff.com

Jump to notable items for Week #204, Week #206 , view the notable archive or my favourites.

About 1 Thing A Week

A website curated by @cchana bringing you 1 Thing A Week, delivered every Monday morning.

You can find a list of all articles in the archive, or read the most popular.

Find out more about 1 Thing A Week or read the privacy policy.

Market

Visit the market and support 1 Thing A Week.

You can find 1 Thing A Week on Twitter, Facebook, Instagram & Reddit