Hvornår skal man bruge: tom og: blank CSS-pseudovælgere

Jeg lavede en frygtelig fejl, da jeg tweetede om :emptyog for :blanket stykke tid siden. Jeg sagde, det :emptyvar ikke nyttigt, og det :blanker meget mere nyttigt end :empty.

Jeg tog fejl!

:emptyer faktisk god nok. Vi har ikke engang brug for det :blank!

En hurtig introduktion

Okay, først, hvad er :emptyog hvad er :blank?

:emptyer en pseudovælger. Det giver dig mulighed for at vælge elementer, der er tomme.

/* This is CSS */
:empty { /* do something */}

Tomme elementer er elementer, der ikke har noget i sig. Det kan ikke engang have et mellemrum.

Tomme elementer kan dog have kommentarer, så længe kommentarerne fylder hele elementet.

:blanker en aktiveret form for :empty. Det giver dig mulighed for at vælge elementer, der har hvide mellemrum i dem:

Begge :emptyog :blanker nyttige, hvis det er nødvendigt:

  1. Stil et tomt element
  2. Opret tomme tilstande

Et eksempel

Lad os sige, at du har en iv>. You will only fill up this with content when an error occurs.

 Whoops! Something went wrong! 

Here, you need to style the .error div. If you don’t use :empty, you need to rely on a class or attribute. This feels redundant.

 Whoops! Something went wrong! 
/* This is CSS */
.error { display: none; background-color: hsl(0, 20%, 50%); padding: 0.5em 0.75em;}
.error[data-state="error"] { display: block;}

But if you use :empty, you don’t need the extra class or attribute. You can style the .error class directly. You don’t even need display: none;!

/* This is CSS */
.error { background-color: hsl(0, 20%, 50%); padding: 0.5em 0.75em;}
.error:empty { padding: 0;}

Here’s a codepen Empty Demo I made for you to play with (try removing the padding: 0; from .error:empty, you’ll see a red background ?).

Let’s say you want to create a todo-list. When your users see the todo-list for the first time, they will probably see zero todo items.

What do you show when there are zero todos?

This zero todo state is what we call an empty state.

If you want to create an empty state for your todo-list, you can add an extra iv> after your

    . When you do so, you can use a combination of :empty and the + (adjacent sibling) or ~ (subsequent sibling) selector to style the empty state.

    • Item 1
    • Item 2
    • Item 3
    /* This is CSS */
    .empty-state { display: none;}
    ul:empty + .empty-state { display: block;}

    I learned how to use :empty this way from Heydon Pickering. Check out Heydon’s article on Inclusive Components if you want to see the todo-list example at work.

    Note: empty states are important. If you need some convincing, check out this article on Invision.

    Taking apart my reasoning

    :empty is often enough in practice. I felt :empty isn’t good enough because of two reasons:

    1. Poor developer experience
    2. I’ll need to trim whitespaces manually with JavaScript

    The first reason is valid, but it isn’t a big deal.

    The second reason is not valid. I assumed I had to trim whitespaces, but I don’t need to.

    I’ll walk you through both of them.

    Let’s go back to the todo-list example. Say we created a todo-list and we have this markup.

    • Item 1
    • Item 2
    • Item 3

    How would you check if :empty was working?

    Well, I would remove each <li> with cmd + x. This command cuts the entire line. When I removed all three

  • , I’ll end up with this markup:


      By now, you’ll know that the HTML above won’t trigger :empty. :empty only works when there are no whitespaces in the element.

      I had to remove the whitespaces for :empty to work, which means a few more keystrokes. This was a chore I hoped I didn’t have to go through.

      But then again, it’s a small problem for a big benefit.

      I say it again. You don’t need to trim whitespaces manually in JavaScript if you use :empty. I made a wrong assumption.

      Let’s go through an example and you’ll see what I mean. We’ll use the todo-list example one more time.

      Say we have this HTML right now:

      • Item 1

      For the empty state to work, we need to remove the final <li> item from

        . If you use plain JavaScript, you can d o this with removeChild.

        // This is JavaScript
        const ul = document.querySelector('ul')const li = ul.children[0]

        I believed (erroneously) that removeChild will produce this HTML:


          If it produces this HTML, I’ll have to trim any whitespace remaining in the list (which is extra JavaScript).

          // This is JavaScript
          const ul = document.querySelector('ul')const li = ul.children[0]
          if (ul.children.length === 0) { ul.innerHTML = ''}

          Like I said, I was wrong. It didn’t produce the above HTML. Instead, this is what it produced:


            Which means we didn’t need the extra JavaScript to trim whitespace!

            Disclaimer: I checked the output on Safari, Chrome, and Firefox. I haven’t checked Edge yet though. I’ll be super grateful if you can help me test it out!

            Here’s the code for this example:

            See the Pen Empty demo with todolist I made (@zellwk) on CodePen.

            :empty is supported on all browsers, and :blank has poor browser support. This gives you plenty of reason to use :empty over :blank today!

            I hope that browser support for :blank improves one day though.

            Wrapping up

            :empty and :blank let you style empty elements and produce empty states easily.

            :blank is better than :empty because it provides us with a better developer experience. But we can’t use :blank because :blank doesn’t have enough browser support.

            :empty is often good enough. You can use it already. Use it all you want! ?

            Give :empty a go and let me know what you think!

            Thanks for reading. Did this article help you in any way? If you did, I hope you consider sharing it. You might help someone out. Thank you!

            This article was originally posted at my blog.

            Sign up for my newsletter if you want more articles to help you become a better frontend developer.