Marco Geertsma Marco Geertsma - 11 days ago 4
CSS Question

Make :focus change css of another class

Let's say i have the following code:

HTML

<div class="container">
<input class="myAwesomeInputBox">
</div>


CSS

.input [type=text]:focus > .//ANY CLASS SOMEWHERE ON THE WEBSITE{
//Some sweet CSS.
}


Obviously this code doesnt work. I want some specific css to get executed when there is focus on my inputbox. Is this at all possible?

I'm not specificly looking for html/css only solutions. Any solution that can achieve this is welcome.

My code above is just an extremely simple example. My question is really simple. Is it possible to change styling on ANY element on your website using the :focus on an input box.

Answer

Using pseudo-classes as an action to modify other elements can only be done if the other elements are direct or indirect siblings or children of the element which has the pseudo-class (such as :hover or :focus). That's because CSS child/sibling selectors are fairly restrictive.

You can use the > selector to select a direct child, and the + selector to select a direct sibling. For example, if you have the following HTML:

<form>
    <input type="text" />
    <input type="submit" />
</form>
<p class="arbitrary">
    This is an arbitrary element. It is neither a child nor sibling of 
    the text field. It cannot be selected as a result of a pseudo-class 
    action on the textfield using CSS, but can be selected using 
    client-side scripting such as JavaScript.
</p>

You could style the button when the text field has focus (because it is a direct sibling of the text field), but there is no possible way to style the arbitrary paragraph as a result of the text field receiving focus (because it is neither a child nor sibling, it is the sibling of a parent) without using client-side scripting (JavaScript, jQuery, etc.).

This CSS would style the submit button, and can be altered to select any direct or indirect child or sibling:

input[type="text"]:focus + input[type="submit"] {
    /* some sweet CSS */
    background-color:green;
}

Using Javascript, of course, you have much greater flexibility. The focus and blur events (Firefox doesn't yet support focusin and focusout) can be used to toggle CSS classes. Here's an example that demonstrates both the CSS and JavaScript techniques of achieving this.

function setFocused() {
  var results = document.querySelectorAll('.arbitrary');
  for (result of results) {
    result.classList.add('focused');
  }
}

function unsetFocused() {
  var results = document.querySelectorAll('.arbitrary');
  for (result of results) {
    result.classList.remove('focused');
  }
}

var results = document.querySelectorAll('input[type="text"]');
for (result of results) {
  result.addEventListener("focus", setFocused);
  result.addEventListener("blur", unsetFocused);
}
input[type="text"]:focus + input[type="submit"] {
  /* some sweet CSS */
  background-color: green;
}

.arbitrary.focused {
  /* even more sweet CSS */
  color: red;
}
<form>
  <input type="text" />
  <input type="submit" />
</form>

<p class="arbitrary">
  This is an arbitrary element. It is neither a child nor sibling of
  the text field. It cannot be selected as a result of a pseudo-class
  action on the textfield using CSS, but can be selected using
  client-side scripting such as JavaScript.
</p>

Here's the jQuery equivalent of the above code, if that's your jam.

$('input[type="text"]').on('focus', function() {
    $('.arbitrary').addClass('focused');
});

$('input[type="text"]').off('focus', function() {
    $('.arbitrary').removeClass('focused');
});

Note that if you decide you want to do something similar, except using a "hover" trigger rather than "focus", you can use the JavaScript mouseover and mouseout functions, or the jQuery .hover() function which takes two arguments (a handler for entering the hover and another for leaving the hover).

Comments