DEV Community

Eris Sulistina
Eris Sulistina

Posted on

Logical Pseudo-Classes in CSS

Logical pseudo-classes are a type of CSS pseudo-class that allow you to select elements based on logical conditions, filtering elements based on structure or relationships within the DOM.


List of Logical Pseudo-Classes

Pseudo-Class Description Example Usage
:not(selector) Selects elements that do not match a given selector button:not(.primary)
:is(selector, …) Simplifies multiple selectors that share the same rule :is(h1, h2, h3)
:where(selector, …) Same as :is(), but always has zero specificity :where(article, section)
:has(selector) Selects elements that contain a child/descendant matching the selector div:has(img)
:nth-child(n) Selects elements based on their order among siblings li:nth-child(2)
:nth-of-type(n) Like :nth-child but only counts elements of the same type p:nth-of-type(2)
:nth-last-child(n) Like :nth-child but counts from the end tr:nth-last-child(1)
:nth-last-of-type(n) Combines :nth-last-child and :nth-of-type div:nth-last-of-type(1)
:first-child Selects the first child of a parent p:first-child
:last-child Selects the last child of a parent li:last-child
:only-child Selects elements that are the only child span:only-child
:only-of-type Selects elements that are the only one of their type within a parent h2:only-of-type
:empty Selects elements that are completely empty (no text or whitespace) div:empty

Big 4

Among all logical pseudo-classes, I highly recommend mastering these four, as they are modern CSS selectors for writing more flexible and efficient rules:

  1. :not
  2. :is
  3. :where
  4. :has

❗ :not() β€” Exclude Elements

:not is used to target all elements that do not match a given selector.

/* Targets all <a> elements without the .btn class */
a:not(.btn) { .... }

/* Targets all <textarea> elements without a rows attribute */
textarea:not([rows]) {
    resize: none;
    field-sizing: content;
}
Enter fullscreen mode Exit fullscreen mode

🧩 :is() β€” Combine Multiple Selectors

:is is used to target elements that match any of the selectors inside it.

/* Targets h1, h2, and h3 elements */
:is(h1, h2, h3) { .... }

/* 
    Targets both:
    1. article > p
    2. article > span
 */
article > :is(p, span) { .... }
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ :where() β€” Like :is(), But Zero Specificity

/* Targets h1, h2, and h3 without specificity */
:where(h1, h2, h3) { .... }

/* 
    Targets both without specificity for p and span:
    1. article > p
    2. article > span
 */
article > :where(p, span) { .... }
Enter fullscreen mode Exit fullscreen mode

πŸ”Ž :has() β€” Target Elements That CONTAIN Other Elements

:has is used to select elements based on whether they have specific children or descendants.

/* Targets buttons that contain an svg */
button:has(svg) { .... }

/* Targets article elements with a direct child <img> */
article:has(> img) { .... }

/* Targets <label> with a required input as next sibling */
label:has(+ [required])::after {
    content: "*"
}
Enter fullscreen mode Exit fullscreen mode

✨ Closing

I hope this post helps level up your CSS skills as a frontend developer.

If you enjoyed this article, don’t forget to πŸ’– save, πŸ—¨οΈ comment, and πŸ” share it with fellow developers!

See you in the next post πŸ‘‹

Top comments (0)