Marcell Ciszek Druzynski

The has selector in CSS

The :has selector in CSS has taken the CSS community by storm, offering the power to accomplish complex tasks with ease. In this post, I will provide a comprehensive overview of how the :has selector works, how to use it, and what it replaces.

March 01, 2023

Has in CSS

The :has selector in CSS has taken the CSS community by storm, offering the power to accomplish complex tasks with ease. In this post, I will provide a comprehensive overview of how the :has selector works, how to use it, and what it replaces.

The :has selector is a relatively new addition to the CSS language, which allows us to select an element based on the presence of a certain type of content within it.

The syntax for how we can use the :has selector is as follows:

1parent: has(child);
1parent: has(child);

This selects the parent element that contains a child element matching the specified selector.

For example, we can select a div element that contains an h2 element inside it and give it a background-color.

1div:has(h2) {
2 background-color: yellow;
3}
1div:has(h2) {
2 background-color: yellow;
3}

The :has selector can also be used in conjunction with other CSS selectors to further refine the selection. For example:

1div:has(h2 a) {
2 background-color: yellow;
3}
1div:has(h2 a) {
2 background-color: yellow;
3}

This selects the div element that contains an a element within an h2 element.

The :has selector can be a powerful tool for simplifying CSS selectors and reducing the amount of HTML markup needed to achieve certain styles or functionality. However, It could be good to know that is not yet supported by all browsers out there, you may need to use an alternative approach.

Two real-time examples

dark mode We can make a simple dark mode using the :has selector without any JavaScript at all which is pretty cool. With this implementation dough there is no storage involved like for example local-storage, in that case we would need local storage.

1body:has(.checkbox-darkmode:checked) {
2 background-color: var(--primary-color);
3 color: var(--secondary-color);
4}
1body:has(.checkbox-darkmode:checked) {
2 background-color: var(--primary-color);
3 color: var(--secondary-color);
4}

Here is a code-pen example.

form validation As with dark mode we can implement a nice form validation without using JavaScript and to only use the :has selector.

1body:has(.checkbox-darkmode:checked) {
2 background-color: var(--primary-color);
3 color: var(--secondary-color);
4}
5
6label:has(+ input:valid) {
7 color: green;
8}
9
10label:has(+ input:invalid) {
11 color: red;
12}
13
14label:has(+ input:valid)::before {
15 content: "✅";
16 margin-right: 5px;
17}
18
19label:has(+ input:invalid)::before {
20 content: "❌";
21 margin-right: 5px;
22}
1body:has(.checkbox-darkmode:checked) {
2 background-color: var(--primary-color);
3 color: var(--secondary-color);
4}
5
6label:has(+ input:valid) {
7 color: green;
8}
9
10label:has(+ input:invalid) {
11 color: red;
12}
13
14label:has(+ input:valid)::before {
15 content: "✅";
16 margin-right: 5px;
17}
18
19label:has(+ input:invalid)::before {
20 content: "❌";
21 margin-right: 5px;
22}

Example code Codepen

Downsides

While the :has selector is a powerful addition to CSS, There are some considerations and limitations to keep in mind of before using the :has selector.

  • Browser support: The :has selector is not yet supported by all browsers, so be sure to check your target audience's browser compatibility before using it. Check out Can I use, perhaps the time you are reading this post it might be supported for all browsers.

  • Selector specificity: The :has selector can only be used once per selector, so it is important to consider its specificity when using it in combination with other selectors.

Resources