CSS pseudo-classes you might need
Tags: css
Published: 2020-02-07 20:16:52

---
title: CSS pseudo-classes you might need
published: true
date: 2020-02-05 14:00:27 UTC
tags: css
canonical_url: https://blog.logrocket.com/css-pseudo-classes-you-might-need/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ae417839foxvnk0bofdy.png
---
**Written by [Ananya Neogi](https://blog.logrocket.com/author/ananya-neogi/)**✏️

A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element.

You might already be familiar with the ones that are commonly used, such as `:hover`.

In this post, we are going to explore some lesser-known and infrequently-used pseudo-classes and their practical use cases.

### `:is()`

This function takes a list of selectors as its argument and selects any element that matches one of the selectors in that list.

Now, what we write like this:

```jsx
article > h1, article > h2, article > h3 {
  color: #555;
}

button:focus, button:hover {
  border: 1px solid orangered;
}
```

will become this:

```jsx
article > :is(h1,h2,h3) {
  color: #555;
}

button:is(:focus, :hover) {
  border: 1px solid orangered;
}
```

As you can see, this is useful for compactly writing large selectors.

Certain older versions of browsers support this functionality as `:matches()` because`:is` [was previously called](https://github.com/w3c/csswg-drafts/issues/3258)`:matches()`.

We can also use the older, vendor-prefixed pseudo-class — `:any()` — which acts in a similar way as `:is()`.

```jsx
article > :-webkit-any(h1,h2,h3) {
  color: #555;
}

article > :-moz-any(h1,h2,h3) {
  color: #555;
}

article > :matches(h1,h2,h3) {
  color: #555;
}
```

### `:focus-within`

This represents an element that has received focus or contains an element that has received focus.

```jsx
<form>
  <label for="name">Name:</label>
  <input type="text" id="name">
  <label for="email">Email</label>
  <input type="email" id="email">
</form>
```

We can modify the form styles when any of its input elements are focused.

```jsx
form:focus-within {
 background: coral;
}
```

Here’s a CSS-only dropdown made possible with `:focus-within`  
([https://codepen.io/ananyaneogi/pen/KKwbyQX](https://codepen.io/ananyaneogi/pen/KKwbyQX))

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

### `:focus-visible`

It applies while an element is in the focused state.

Most browsers show a _focus ring_ by default in this case.

This selector is useful for providing a different focus indicator based on how the user is interacting with the element (i.e with a mouse, a keyboard, etc.)

In this example, when we navigate the links with a keyboard (i.e. by tabbing), only then will the focus styles be applied.

This helps appy prominent styles to guide users who are navigating with a keyboard without altering focus states when using a mouse.

{% codepen https://codepen.io/ananyaneogi/pen/bGNZExY %}

### `:only-child` and `:only-of-type`

`:only-child` selects an element that is the ONLY child of a parent. That means only one element exists within that parent. Even if it’s a different element type, it won’t be considered an only child. One element, no exceptions!

```jsx
p:only-child {
      color: magenta;
    }


    <article>
      <p>A simple paragraph</p> <!-- p will be of magenta colour -->
    </article>
    
    <!-- ❌ no element selected because p is not the only child -->
    <article>
      <h1>Heading</h1>
      <p>A simple paragraph</p>
    </article>
```

`:only-of-type` selects an element that is the ONLY child of a particular type within a parent. Having other siblings of different types is fine.

```jsx
p:only-of-type {
color: magenta;
```
```jsx
}
```
```jsx
<!-- p will be of magenta colour, because even though article contains more than one child but still <p> is the only one of it's own type -->
<article>
  <h1>Heading</h1>
  <p>A simple paragraph</p>
</article>
```

Here’s a practical example using `:only-child`, adding a “Hurry, last item remaining” type of message to a product card if it’s the only product card remaining.

{% codepen https://codepen.io/ananyaneogi/pen/PowLGLK %}

### `:not()`

This represents elements that do not match a list of selectors it takes as the argument.

```jsx
<article>
  <p>A simple paragraph</p>
  <span>Span text</span>
</article>


/* Everything except the <p> inside the <article> will be of magenta colour! */
article :not(p) {
  color: magenta;
  }
```

This is not a very practical example but we can use `:not()` along with other pseudo-classes to achieve interesting results. We’re going to see that next.

**Note** : nesting of `:not` i.e `:not(:not(...))` is invalid.

### `:empty`

This represents any element that has no children. Children can be either element nodes or text including whitespace.

```jsx
/* Selects any <span> that contains no content */
span:empty {
   background: magenta;
}
```

Here’s an example of eliminating empty tags that contain no content using `:empty` along with `:not()`.  

{% codepen https://codepen.io/ananyaneogi/pen/oNNBvzR %}

### `:placeholder-shown`

This represents any input element that is currently displaying the placeholder text.

In this example, we are highlighting the required fields in the form that are yet not filled by the user.

We are signaling that the fields are not yet filled in by simply targeting the inputs whose placeholder is still showing.

{% codepen https://codepen.io/ananyaneogi/pen/abzMbJE %}

If you look closely in the example above, you’ll notice that another pseudo-class, `:required,` is used along with  `:placeholder-shown`.

`:required` is one of the many pseudo-classes related to forms that we have at our disposal. Next, we are going to look at some form-related pseudo-classes that make our form’s user experience better.

### `:required`

This represents any input element that has the required attribute set on it. It is useful for highlighting fields that must be entered by the user before the form can be submitted.

### `:read-only`

This represents an element that is not editable by the user.

### `:invalid</code`

This represents any input form element whose contents fail to validate.

### `:valid`

This represents any input form element whose contents validate successfully.

Here’s an example using the previously mentioned form-related pseudo-classes:  

{% codepen https://codepen.io/ananyaneogi/pen/zYxbYPp %}

### Conclusion

Remember to always refer to the browser compatibility before using them in production.

However, don’t let the browser inconsistency stop you from experimenting with new things: just keep a fallback handy and you’re good to go.

Find more documentation related to these pseudo-classes on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes).

* * *
## Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, [try LogRocket.](https://logrocket.com/signup/) 

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/403rye2ptzx994uhktk1.png)

[LogRocket](https://logrocket.com/signup/) is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — [Start monitoring for free.](https://logrocket.com/signup/)
* * *

The post [CSS pseudo-classes you might need](https://blog.logrocket.com/css-pseudo-classes-you-might-need/) appeared first on [LogRocket Blog](https://blog.logrocket.com).