Here’s what I didn’t know about :where()

This is part 4 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I’m trying to find out what I didn’t know about the :where() pseudo-class.


Okay, I’ll be honest. When I heard about the :where() pseudo-class for the first time, I wasn’t impressed because reading a rule like the following hurt my brain.

:where(header, main, footer) p:hover {
  color: red;
}

It feels like using a shorthand property instead of longhand properties; fewer lines of code, but harder to process. I didn’t get the point, but a few days ago it clicked.

Here’s what I didn’t know about :where():

You can use it to lower the specificity of a selector

I believe it was on Andys blog where I saw this smart rule:

ul[class] {
  margin: 0;
  padding: 0;
  list-style: none;
}

If a <ul> has no class, it’s probably a list in the true sense, so leave it untouched and display bullets. If the list has a class, it’s semantically still a list (in most browsers), but it’s likely that it doesn’t look like one, so reset the styling. Yeah, I know, dangerous assumptions, but it worked well for me in the past. The only issue I had with this solution is the high specificity caused by the combination of a tag and a class selector. If I wanted to change one of the default properties using just a class selector, it wouldn’t work.

<ul class="space">
  <li>HTML</li>
  <li>CSS</li>
  <li>JS</li>
</ul>
ul[class] {
  margin: 0;
  padding: 0;
  list-style: none;
}

.space {
  /* This doesn't apply because ul[class]
   has higher specificity than .space */
  margin: 2rem;
}

Open the first example on CodePen.

This is where :where() comes into play. No matter which selectors you pass to the pseudo-class, :where() will always have a specificity of 0.

ul:where([class]) {
  margin: 0;
  padding: 0;
  list-style: none;
}

.space {
  /* This applies because .space has higher 
  specificity than ul:where([class]) */
  margin: 2rem;
}

Even though the selector contains a tag, a pseudo-class and an attribute, only the tag selector adds to the specificity.

Open the second example on CodePen.

Another great example is input styling (thanks for the tip, Christopher).

input:where([type="text"], 
            [type="email"],
            [type="password"]) {
  border: 2px solid #000;
}

[aria-invalid] {
  border-color: red;
}

or if you’re a fan of the :not() selector:

input:where(
  :not(
    [type="button"], 
    [type="reset"],
    [type="image"]
  )
) {
  border: 2px solid #000;
}

Open the third example on CodePen.

:where() is a forgiving selector

If a list of selectors contains an invalid selector, none of the selectors will match.

<button>
  Send
</button>
/* The background color won't change on :hover or :focus
 because the invalid :touch pseudo-class makes the whole
list invalid  */
button:focus,
button:hover,
button:touch {
  background: red;
}

Open example 4 on CodePen.

If you use :where() instead, :focus and :hover will still match.

button:where(:focus,
             :hover,
             :touch) {
  background: red;
}

Open example 4 on CodePen.

Conclusion

I haven’t used :where() in production yet, but considering that browsers support is pretty great, I’m going to try it out soon. The only concern I still have is the cognitive overload selectors like :where() or :not() create.

My blog doesn’t support comments yet, but you can reply via blog@matuzo.at.


This content originally appeared on Manuel Matuzović - Blog and was authored by Manuel Matuzović

This is part 4 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I'm trying to find out what I didn’t know about the :where() pseudo-class.


Okay, I’ll be honest. When I heard about the :where() pseudo-class for the first time, I wasn’t impressed because reading a rule like the following hurt my brain.

:where(header, main, footer) p:hover {
  color: red;
}

It feels like using a shorthand property instead of longhand properties; fewer lines of code, but harder to process. I didn’t get the point, but a few days ago it clicked.

Here’s what I didn’t know about :where():

You can use it to lower the specificity of a selector

I believe it was on Andys blog where I saw this smart rule:

ul[class] {
  margin: 0;
  padding: 0;
  list-style: none;
}

If a <ul> has no class, it’s probably a list in the true sense, so leave it untouched and display bullets. If the list has a class, it’s semantically still a list (in most browsers), but it’s likely that it doesn’t look like one, so reset the styling. Yeah, I know, dangerous assumptions, but it worked well for me in the past. The only issue I had with this solution is the high specificity caused by the combination of a tag and a class selector. If I wanted to change one of the default properties using just a class selector, it wouldn’t work.

<ul class="space">
  <li>HTML</li>
  <li>CSS</li>
  <li>JS</li>
</ul>
ul[class] {
  margin: 0;
  padding: 0;
  list-style: none;
}

.space {
  /* This doesn't apply because ul[class]
   has higher specificity than .space */
  margin: 2rem;
}

Open the first example on CodePen.

This is where :where() comes into play. No matter which selectors you pass to the pseudo-class, :where() will always have a specificity of 0.

ul:where([class]) {
  margin: 0;
  padding: 0;
  list-style: none;
}

.space {
  /* This applies because .space has higher 
  specificity than ul:where([class]) */
  margin: 2rem;
}

Even though the selector contains a tag, a pseudo-class and an attribute, only the tag selector adds to the specificity.

Open the second example on CodePen.

Another great example is input styling (thanks for the tip, Christopher).

input:where([type="text"], 
            [type="email"],
            [type="password"]) {
  border: 2px solid #000;
}

[aria-invalid] {
  border-color: red;
}

or if you're a fan of the :not() selector:

input:where(
  :not(
    [type="button"], 
    [type="reset"],
    [type="image"]
  )
) {
  border: 2px solid #000;
}

Open the third example on CodePen.

:where() is a forgiving selector

If a list of selectors contains an invalid selector, none of the selectors will match.

<button>
  Send
</button>
/* The background color won't change on :hover or :focus
 because the invalid :touch pseudo-class makes the whole
list invalid  */
button:focus,
button:hover,
button:touch {
  background: red;
}

Open example 4 on CodePen.

If you use :where() instead, :focus and :hover will still match.

button:where(:focus,
             :hover,
             :touch) {
  background: red;
}

Open example 4 on CodePen.

Conclusion

I haven’t used :where() in production yet, but considering that browsers support is pretty great, I’m going to try it out soon. The only concern I still have is the cognitive overload selectors like :where() or :not() create.

My blog doesn't support comments yet, but you can reply via blog@matuzo.at.


This content originally appeared on Manuel Matuzović - Blog and was authored by Manuel Matuzović


Print Share Comment Cite Upload Translate Updates
APA

Manuel Matuzović | Sciencx (2022-01-25T00:00:00+00:00) Here’s what I didn’t know about :where(). Retrieved from https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/

MLA
" » Here’s what I didn’t know about :where()." Manuel Matuzović | Sciencx - Tuesday January 25, 2022, https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/
HARVARD
Manuel Matuzović | Sciencx Tuesday January 25, 2022 » Here’s what I didn’t know about :where()., viewed ,<https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/>
VANCOUVER
Manuel Matuzović | Sciencx - » Here’s what I didn’t know about :where(). [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/
CHICAGO
" » Here’s what I didn’t know about :where()." Manuel Matuzović | Sciencx - Accessed . https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/
IEEE
" » Here’s what I didn’t know about :where()." Manuel Matuzović | Sciencx [Online]. Available: https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/. [Accessed: ]
rf:citation
» Here’s what I didn’t know about :where() | Manuel Matuzović | Sciencx | https://www.scien.cx/2022/01/25/heres-what-i-didnt-know-about-where-2/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.