Introduction

Selecting a parent element has long been impossible to do using just CSS, but a pseudo-class, <^>:focus-within<^>, changes that story somewhat. It allows to style an element when it has focus, but also when any of its inner elements (descendants) have focus. A prime example is with a form where you'd want a container element to be styled a certain way when the user focuses into one of the input elements.

HTML and CSS Code

focus-within illustration for: HTML and CSS Code

Here's an example of using <^>:focus-within<^> with a form. Let's start with this markup:

				
					
&lt;form tabindex="0" class="myForm"&gt;

 &lt;h3&gt;What's your favorite color?&lt;/h3&gt;

 &lt;input type="text"&gt;

&lt;/form&gt;

				
			

And our CSS rules are the following:

				
					
.myForm:focus-within {

 background: #f8f8f8

 repeating-linear-gradient(

 45deg,

 transparent,

 transparent 35px,

 rgba(255, 255, 255, 0.5) 35px,

 rgba(255, 255, 255, 0.5) 70px

 );

}

.myForm:focus-within::before {

 content: "I'm a happy selected form!";

 color: rgb(239, 187, 53);

}

				
			

Working Demo

Below you can see the result if you're using a supporting browser. Notice how the different background is applied to the containing form element when the form itself is focused or when either of the inputs are focused.

If we had used the good old <^>:focus<^> pseudo-class instead of :focus-within, our container form would be styled only when the focus is on the form itself, but not when the inputs are focused:

<form tabindex="0" class="myForm">

What's your favorite color?

<input type="text" placeholder="Your answer">

</form>

<style> .myForm:focus-within { background: #f8f8f8 repeating-linear-gradient( 45deg, transparent, transparent 35px, rgba(255, 255, 255, 0.5) 35px, rgba(255, 255, 255, 0.5) 70px ); } .myForm:focus-within::before { content: "I'm a happy selected form!"; color: rgb(239, 187, 53); } .myForm { text-align: center; background: #f8f8f8; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); padding: 2rem; border: 2px solid #4AAE9B; } .myForm h3 { margin: 0; } .myForm input { padding: .5rem 0; margin: .75rem auto; font-size: 1.3rem; max-width: 500px; text-align: center; background-color: rgba(255, 255, 255, 0.4); }

input::placeholder { color: black;} </style>

<br>

_Thanks to Lea Verou for the CSS background pattern._

Conclusion

In order for <^>:focus-within<^> to work as expected, you'll have to make sure that the inner elements of the container are focusable. Input elements are focusable by default, but <^>div<^>, <^>img<^> or <^>p<^> elements, for example, are not. The tabindex attribute can be used to make an element focusable. The container element should also be focusable in order to receive the styling when focusing from just the container.

Browser Compatibility Check: As of 2020, all modern browsers support focus-within, but check Can I Use for detailed, version-specific browser support.