How To Use The CSS :Has Selector
Published: 2023-10-13 16:11:15

by [Joyce Foster](https://blog.openreplay.com/authors/joyce-foster)

<blockquote><em>
The recent :has() selector lets you apply styles to parents and other ancestors, and this article will show you how to use it for your web app development.
</em></blockquote>

<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>

In the world of CSS, selectors are the workhorse powering the beautiful and responsive designs we see on the web. They allow developers to select and style HTML elements based on their properties, position, and relationships.

A more [recent CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:has)/pseudo-class known as `:has`  allows you to choose every element that has child elements matching the selector you provide to the `:has()` function. It is an important solution in CSS beyond being a simple "parent" selector.

Using the `:has()` selector, you can apply styles to a parent or ancestor HTML element. This allows us to extend the selector's scope to include one or multiple siblings or children.

In this article, we will look at the CSS `:has` selectors and multiple examples of their use in your code.



## When to use the `:has` selector

The `:has()` selector is a CSS pseudo-class that allows you to select an element if it contains certain child elements. It is a powerful CSS tool you could use for the following purposes:


- **Styling the parent of a child element:** You could use the `:has()` selector to style a `<div>` element if it contains a `<p>` element.


- **Conditionally adding or removing styles:** You can use the `:has()` selector to add a border to a `<div>` element if it contains a certain number of child elements.


- **Selecting elements based on their content:** You can use the `:has()` selector to select all `<div>` elements that contain a child element with the class of  `"important"`.

The `:has()` selector can be used with any valid CSS selector, including other pseudo-classes. This makes it a very versatile tool that can be used in various ways.

Here is a little snippet of how the `:has()` selector can be used:
```css
/* Select all <div> elements that contain a <p> element. */
div:has(p) {
 background-color: blue;
}
  
/* Select all <div> elements that contain a child element with the class "important". */
div:has(.important) {
 border: 1px solid black;
}   
/* Select all <div> elements that contain at least two child elements. */
div:has(> * + *) {
 padding: 10px;
}
```
The code above shows practical examples of how the `:has` selector can be used. But before we dive deeper into using the `:has` selector, let’s examine why the selector is important.



## Project Setup

To start this project, you can clone the starter code from this [GitHub repo](https://github.com/joycefoster642/-has-css-project). The completed repo is also in the repo, but you need to use the starter code to follow along with this tutorial.

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691410881564_Screenshot+2023-08-07+132101.png)


The image above shows what our project looks like when launched on the browser.

**Note:** The project is just a simple blog-like demo to show you how the `:has` pseudo-class is generally used.


## Forward vs. Reverse Selections

Previously, developers could only select forwards, but with the `:has`  selector, you can now select backward as well.

Now, we are going to select the parent of an element. In the past, this was usually done like this:
```css
article + article {
 background-color: pink;
}
```
Here, we selected an `article` and another `article` using the adjacent sibling selector, then we changed the `background-color` to pink. This is the result below:


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691410993041_Screenshot+2023-08-07+132223.png)


As you can notice, the color of the second and third article is changed. This is because they are adjacent to each other. So, it selected forwards and not backward. Now, let's do this in reverse with the `:has` selector.
```css
article:has(+ article) {
 background-color: coral;
}
```
In the code above, we simply say, if the article has an adjacent article, select the first two articles.


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691411143494_Screenshot+2023-08-07+132505.png)


Now, notice it selected the first and second articles this time around.


## Selections based on child elements

With `:has` we can do more than select the parent; we can also select the child elements.

```css
article:has(span) .bold {
 background-color: lightyellow;
}
article:has(span) .italic {
 text-decoration: underline;
}
```
In the `index.html` file, we used `span` to apply a bold and italic class to articles 2 and 3. In our CSS file, we selected our `span`  using the `article:has(span)` syntax. This is the result below:


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691411412984_Screenshot+2023-08-07+132941.png)


Here, you can see the changes applied to the bold and italics in the second and third articles. We have not only selected the articles but what the `span` class was applied to.


<CTA_Middle_Basics />


## Using `:has` with the `:not` selection

In this section, we will look at how to use `:has` pseudo-class with `:not`.
```css
article:not(:has(span)) {
 background-color: yellowgreen;
}
```
This is the result below:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691411577078_Screenshot+2023-08-07+133227.png)


It only changes the article that does not have a `span` class inside.

The `:has` selector also supports the `0R` logical conditions.
```css
article:has(p, .button) {
 background-color: royalblue;
}
```
This is the result below:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691411959411_Screenshot+2023-08-07+133847.png)


Here, we could select an article with a paragraph `OR` any article with a `button` class. The three articles are selected because they all have a `p` HTML tag. But if we are to remove the `p` tag, only the last article with the “buy now” `button` class will remain colored.


## CSS `:has` Use Case and Examples

In this section, we will look at more practical use cases and examples when using the `:has` selector.

### Nav Menu Example
This brings us to the next part of our project, which looks like this:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1690486148163_Screenshot+2023-07-27+202807.png)


Here, we moved our mouse over to locations, and you can see the different locations we have when we hover over locations.

When we don’t hover over locations and employees, you will notice that there is no indication that there is any drop-down menu at all. If we use modifier classes for this, we would have to manually go into the HTML file and write the code. However, we can accomplish this with the `:has` pseudo-class.
```css
.nav__item:has(.nav__submenu)::after {
 font-family: "Font Awesome 5 Free";
 font-weight: 400;
 content: "\f150";
 margin-left: 1rem;
}
```
In the above code, we are saying, if the `.nav__item` has a `.nav__submenu` inside it, apply the design to only the first two navbars. This is the result below:


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1690489438922_Screenshot+2023-07-27+210237.png)


### Modal Example
We can do a modal with JavaScript, but now, we can also do it with the `:has` selector. This next example takes us to the next part of the project, which looks like this:


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691409295482_Screenshot+2023-08-07+125135.png)


When the checkbox is ticked, nothing happens. But we can easily make something happen with the `:has` pseudo-class.
```css
.awesome:has(.awesome__terms:checked) {
 display: none;
}
```
The `.awesome` class is our modal. Then we said if we have `.awesome__terms: checked` let the following page show up when we click the checkbox again:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691416029325_Screenshot+2023-08-07+144652.png)

Perfect!

### Light & dark mode example
This is another quick example of how we can apply something if it's checked.
```css
.three:has(.lightswitch:checked) {
 background-color: var(--COLOR);
 color: var(--BGCOLOR);
}
```
Once we apply the code above and click on “Toggle Dark Mode”, this is the result below:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1691416119280_Screenshot+2023-08-07+144800.png)


Now, you can seamlessly toggle between light and dark modes.

### Input Validation Example

Our final example leads us to the part of our project that looks like this:


![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1690833898100_Screenshot+2023-07-31+210438.png)


The image above shows the `label` containing the text “Name”, and a text input. Now, we are going to select something in reverse. Before, we could only select forward, so the `label` would have to come after the text `input`. We can now change the `label` based on what’s in the `input`.
```html
<div>
 <label for="name">Name:</label>
 <br />
 <input
   class="name"
   type="text"
   name="name"
   id="name"
   required
   pattern="^\[A-Z\][A-z]{2,}"
 />
</div>
```
On our `index.html` code above, we applied a pattern to the `input`. Here, we have a `required pattern` with a [Regex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions) that says the text must start with a capital letter and is going to be at least 3 characters. In our `style.css`, we looked included the following code:
```css
label:has(~ .name:valid)::after {
 content: '✔️';
 color: limegreen;
 margin-left: 1rem;
 font-size: 3rem;
}
```
This is the result below:

![-](https://blog.openreplay.com/images/how-to-use-the-css-has-selector/images/s_EA431FF8635A49902F537CE47F71F8304A2BD6C9C00462B1C9CCA74FAE21067C_1690837140693_Screenshot+2023-07-31+215845.png)


The name “Joyce” meets the requirement of starting with a capital letter and being up to three words; hence, the green check mark appears.

Now that we have come to the end of this tutorial, I hope you learned a thing or two about the `:has` CSS selector/pseudo-class.


## Conclusion

The CSS `:has` selector presents an innovative approach to solving complex styling challenges in web development. Throughout this article, we have explored the capabilities and potential use cases of this powerful selector, which allows us to target elements based on their descendants.

By leveraging the `:has` selector, web developers can enhance the efficiency and flexibility of their CSS code, streamlining the selection process and reducing the need for unnecessary classes and nested structures.

This selector empowers developers to create cleaner, more maintainable code while preserving the HTML structure's integrity.