loading...
Cover image for Grab your user's attention with the :focus-within CSS selector

Grab your user's attention with the :focus-within CSS selector

vtrpldn profile image Vitor Paladini ・2 min read

Here's a neat little trick:

You can use the :focus-within selector to style the parent of a focused element.

An example of how on focus overlay works

That allows you to create some interactive form UI without a single line of JavaScript. Try the example below:

This demo uses :focus-within, plus the ::before pseudo-selector and some absolute positioning magic. We'll go through the details but you can check the full source below.

:focus-within selector + ::before pseudo-elements + absolute positioning

All in a single declaration block! Let's have a look at the most important part of this example.

body:focus-within::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
}
Enter fullscreen mode Exit fullscreen mode

body:focus-within

This selector will apply styles whenever there is focus... within the body!

Oh, and :focus-within works with any element. We're sticking with body only for this example.

You can be creative and come up with .literallyAnyElement:focus-within and use this selector as you please.

body:focus-within::before + absolute positioning

In our example, that means that whenever any field is focused on the body, a ::before pseudo-element will be created with those styles:

content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
Enter fullscreen mode Exit fullscreen mode

The content: '' property is required for pseudo-elements and everything else are properties used to create a dark, transparent overlay that fills the whole screen!

Extra stuff to make it work properly

Keep in mind that you still need to make a couple of tweaks to make the overlay work perfectly.

html,
body {
  height: 100vh;
}
Enter fullscreen mode Exit fullscreen mode

This makes sure that the overlay fills the whole screen even if there isn't enough content on the page.

form {
 position: relative;
Enter fullscreen mode Exit fullscreen mode

This position: relative; ensures that the overlay renders below the form.


And that's it for this week's neat little trick. Thanks for reading!

Make sure the check the other tricks in the series and follow me on Twitter if you found any of my articles helpful 😄


EDIT: Make sure to check Andrew's suggestion in the comments below!


Photo by Stefan Cosma on Unsplash

Discussion

pic
Editor guide
Collapse
link2twenty profile image
Andrew Bone

Very cool, I'd make one slight change to prevent a repaint.

I'd move your :focus-within to form using box-shadow and remove the before.

form {
  position: relative;
  display: inline-block;
  border-radius: 4px;
  background: white;
  padding: 16px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0);
  transition: box-shadow 0.1s ease;
}
form:focus-within {
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.7);
  transition-duration: 300ms;
}
Enter fullscreen mode Exit fullscreen mode

It also means things behind the shadow can still be interacted without having to wait for the shadow to fade away.

Collapse
vtrpldn profile image
Vitor Paladini Author

Hey, Andrew. Great addition, thanks 😄

Collapse
devaicom profile image
devAicom

Thanks for the tip : allow to use this technique only on forms, without the problem that links (or other elements) can gain focus too.

Collapse
michaelandreuzza profile image
michael-andreuzza

I applied this a couple of weeks back oj my newsletter unicornsfeed.com and works amazing.

Collapse
vtrpldn profile image
Vitor Paladini Author

Is there a public link to that newsletter? If so, please share 🙂

Collapse
michaelandreuzza profile image
Thread Thread
vtrpldn profile image
Vitor Paladini Author

Now that's a good looking newsletter if I've ever seen one, subscribed!

Thread Thread
michaelandreuzza profile image
michael-andreuzza

Oh, wow...what a honor. Thank you for that Vitor.

Is it the fact that is black that you like it?

Thread Thread
vtrpldn profile image
Vitor Paladini Author

It being black definitely caught my attention (I can't remember any other mail template that's black) but I also liked the content sections and the shade of blue that you've used as accent color. Great job 😄

Thread Thread
michaelandreuzza profile image
michael-andreuzza

Boom, thank you.
It took me a bit to get there. Really glad you like it. I won't disappoint you. Promised.

Collapse
devaicom profile image
devAicom

Hi,
Very interesting article, and a real plus for end user.
I have a small question about this technique : how would you apply it only on forms. I mean : i want to make the current form more visible (with a pseudo transparent element on body to "mask" anything else), but form inputs are not the only elements which can gain focus : links can too, and i don't want my page to turn dark at any click.
Any idea ?
Thanks

Collapse
dailydevtips1 profile image
Chris Bongers

Wow nice one! Must try this out one day!

Collapse
vtrpldn profile image
Vitor Paladini Author

Please do! I love when modern CSS allows us to make stuff that used to be JS only

Collapse
rowemore profile image
Rowe Morehouse

Awesome, love it. These little #ui UI interactions very much influence #ux user experience and conversion. #CRO