Utilizing pseudo-classes like :hover
or :focus
to modify different elements is limited to siblings or children of the element with the pseudo-class. This limitation is due to the constraints of CSS child/sibling selectors.
To target a direct child, use the >
selector and for a direct sibling, use the +
selector. For instance, consider the following HTML example:
<form>
<input type="text" />
<input type="submit" />
</form>
<p class="arbitrary">
This paragraph is not a child or sibling of the text field. It cannot be styled through CSS pseudo-classes but can be targeted using client-side scripting like JavaScript.
</p>
You can style the submit button when the text field is focused (as they are direct siblings), but styling the arbitrary paragraph based on focus of the text field isn't possible through CSS alone (since it's neither a child nor sibling, rather a sibling of their parent) without resorting to client-side scripting like JavaScript or jQuery.
The following CSS snippet demonstrates styling the submit button, which can be adjusted to target any direct or indirect child or sibling:
input[type="text"]:focus + input[type="submit"] {
/* some cool CSS rules */
background-color: green;
}
JavaScript allows much more flexibility. The focusin
and focusout
events enable toggling CSS classes. Here's an example showcasing both CSS and JavaScript methods:
function setFocused() {
document.querySelectorAll('.arbitrary').forEach((result) => {
result.classList.add('focused');
});
}
function unsetFocused() {
document.querySelectorAll('.arbitrary').forEach((result) => {
result.classList.remove('focused');
});
}
document.querySelectorAll('input[type="text"]').forEach((result) => {
result.addEventListener("focusin", setFocused);
result.addEventListener("focusout", unsetFocused);
});
input[type="text"]:focus + input[type="submit"] {
/* some nice CSS */
background-color: green;
}
.arbitrary.focused {
/* more nice CSS */
color: red;
}
<form>
<input type="text" />
<input type="submit" />
</form>
<p class="arbitrary">
This paragraph is neither a child nor sibling of the text field. It cannot be styled by CSS pseudo-classes but can be selected using
client-side scripting such as JavaScript.
</p>
If you prefer working with jQuery, here's the jQuery equivalent of the code above:
$('input[type="text"]').on('focus', function() {
$('.arbitrary').addClass('focused');
});
$('input[type="text"]').off('focus', function() {
$('.arbitrary').removeClass('focused');
});
For similar functionality using a "hover" trigger instead of "focus," you can utilize JavaScript's mouseover
and mouseout
functions, or jQuery's .hover()
function with separate handlers for hover in and out actions.