$ cd ~/talks/modern-css-selectors

Modern CSS Selectors⁠

I can :has() parent? The sibling combinators I love, :where() and :is() and how they change specificity, and :has(), the parent selector we waited years for.

$ open slides

  1. Modern CSS Selectors I can :has() parent?
  2. Hello! 👋 I’m Luke DeWitt Director of Web Services
  3. I love CSS ❤
  4. I love CSS ❤
  5. - Direct Sibling (Adjacent Sibling Combinator) - The adjacent sibling combinator (+) separates two selectors and matches the second element only if it immediately follows the first element, and both are children of the same parent element .element + .element Favorite CSS Selectors (yes, like children, you can have favorites) MDN Link:…
  6. I was told there’d be no math 🧮
  7. - Indirect Sibling (General Sibling Combinator) - The general sibling combinator (~) separates two selectors and matches all iterations of the second element, that are following the first element (though not necessarily immediately), and are children of the same parent element. .element ~ .element Favorite CSS Selectors MDN Link:…
  8. Some new favorites, perhaps? 🤗
  9. MDN Link: https://developer.mozilla.org/en-US/docs/Web/CSS/:where :where() “takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list”
  10. :where()
  11. :where() Let’s get SASSy
  12. MDN Link: https://developer.mozilla.org/en-US/docs/Web/CSS/:is :is() “takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list”
  13. … wait a second… :where() :is() this going? “takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list”
  14. :where( ) :is() Listing the damn selectors
  15. Key differences Listing Selectors vs Modern Selectors - More compact - Forgiving
  16. Forgiving Selectors �� ��
  17. :where( ) :is()
  18. Specificity
  19. A quick refresher on specificity 🤔
  20. Specificity Specificity is the algorithm used by browsers to determine the CSS declaration that is the most relevant to an element, which in turn, determines the property value to apply to the element.
  21. Guess the Specificity 001 0
  22. Guess the Specificity 002 0
  23. Guess the Specificity 011 0
  24. Guess the Specificity 011 2
  25. Guess the Specificity NEVER USE !IMPORTANT
  26. Specificity
  27. Specificity 0110 0020 0010
  28. Specificity 0010 0011 0100 … on the parent element
  29. Specificity Specificity of the most specific selector in the argument list, in this case, 10 Specificity of the 0, regardless of the argument list
  30. :where( ) :is()
  31. 5/10 🫤
  32. :has() “represents an element if any of the relative selectors that are passed as an argument match at least one element when anchored against this element” WE’RE TALKIN’ PARENT SELECTORS, BABY!!!!
  33. MDN Link: https://developer.mozilla.org/en-US/docs/Web/CSS/:has :has() the future has arrived!!
  34. :has() the future has arrived!!
  35. … tip of the iceberg I can :has() CSS?
  36. :has()
  37. 9/10 🤩
  38. Go forth and style! 😎
1 / 41
download pdf ↓

$ cat notes.md

I love CSS. You know that by now.

Some old favorites

Yes, like children, you can have favorites:

  • Adjacent sibling (+): .element + .element matches an element only if it immediately follows the first one, with the same parent.
  • General sibling (~): .element ~ .element matches every following sibling, not just the next one.

Some new favorites: :where() and :is()

Both take a selector list and match any element that matches one of the selectors in it. So instead of listing the damn selectors:

.container h1,
.container .element {
  color: red;
}

you can write:

.container :is(h1, .element) {
  color: red;
}

Wait a second… :where() and :is() have the exact same definition on MDN. Where is this going?

Compared to listing selectors, both are more compact, and both are forgiving: one invalid selector in the list doesn’t throw out the whole rule, the way it would in a regular selector list.

The difference is specificity:

  • :is() takes the specificity of the most specific selector in its list.
  • :where() always has a specificity of 0, whatever you put in it.

That makes :where() great for defaults that are easy to override. (A quick refresher on specificity is in the slides, including the most important rule: never use !important.)

My rating: 5/10. Handy, not life-changing.

:has()

We’re talkin’ parent selectors, baby! :has() matches an element if any of the selectors you pass it match something inside it:

article:has(h2) {
  color: red;
}

Style a parent based on its children, finally. And that’s just the tip of the iceberg.

My rating: 9/10. The future has arrived.

Go forth and style! More on MDN: :where(), :is() and :has().

visitor@whatadewitt: ~