13

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.

Marco Geertsma
  • 803
  • 2
  • 9
  • 28
  • 1
    Which element should be styled on focus of the input tag? I think you may know this already but your above code doesn't work because the element with `class=container` is not a child of the input. – Harry Sep 12 '14 at 11:17
  • 2
    This isn't possible, the clue is in the name, **cascading** style sheets. – Prisoner Sep 12 '14 at 11:17
  • @Hashem Qolami, im not trying to style my outer div. I'm trying to style any div which is not a child of the input box. For example have an input box in the header and put display:none on the entire footer. In my opinion this is not a duplicate of that question. – Marco Geertsma Sep 12 '14 at 11:22
  • @MarcoGeertsma So isn't it an outer `div` which you've shown within your posted code? You can't target any `
    ` but only the next **siblings**.
    – Hashem Qolami Sep 12 '14 at 11:25
  • I'll edit my question for you. – Marco Geertsma Sep 12 '14 at 11:25
  • 2
    jQuery to the rescue! http://jsfiddle.net/hpfy8h57/1/ – Turnip Sep 12 '14 at 11:28
  • @MarcoGeertsma The update doesn't make the question clear. Please be more specific, Your posted code doesn't make sense and it doesn't explain what you are really after for. Also if you're not looking for CSS only solutions, edit the tags to involve the others. – Hashem Qolami Sep 12 '14 at 11:30
  • @HashemQolami I didnt add more tags simply because i didnt know what languages could do this. I could add C++ for all i know if that could help. – Marco Geertsma Sep 12 '14 at 11:31
  • @MarcoGeertsma: You could add Javascript, jQuery as two possible options. But if you could provide a more specific markup, it could be better for the answerers to provide even more efficient examples. – Harry Sep 12 '14 at 11:33
  • @MarcoGeertsma Still the posted code is misleading. `.input [type=text]:focus > .container` gives the impression that you want to target the parent element. However I'll reopen the topic but please consider refining the posted code. – Hashem Qolami Sep 12 '14 at 11:38
  • Please note that the CSS you show doesn't even match the HTML you show. Also your CSS suggests your `input` elements have a CSS class `input`. If so, your selector `.input [type=text]:focus` will **never** match anything because you carelessly didn't mind the space character in it, which **has a special meaning in CSS** - it's a descendant selector. `input` elements **cannot have descendants** . – connexo May 15 '20 at 15:00

3 Answers3

28

Using pseudo-classes (such as :hover or :focus) to modify other elements can only be done if the other elements are siblings or children of the element which has the pseudo-class. 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 focusin and focusout events can be used to toggle CSS classes. Here's an example that demonstrates both the CSS and JavaScript techniques of achieving this.

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 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).

Woodrow Barlow
  • 8,477
  • 3
  • 48
  • 86
  • 1
    Although my answer will probably do what its suppose to, @Woodrow's solution is way better and cleaner. Id opt for this solution. – morne Sep 12 '14 at 12:10
  • @Woodrow it is now possible to simply change the style of a parent element when a child element is focused with this pseudo-class: ````parent:focus-within````. See more in this SO answer: https://stackoverflow.com/a/45674671/15145107 – MikhailRatner Aug 04 '22 at 14:57
3

Maybe add a ID

<div class="container">
   <input class="myAwesomeInputBox" id='myAwesomeId' type="text">
</div>

and add and remove a class like this. Wont that solve your problem.

$('#myAwesomeId').on({
    focus: function () {
        $(this).addClass('focused');
    },

    blur: function () {
        $(this).removeClass('focused');
    }
});

CSS

input.focused {
    border:3px solid blue;
}

FIDDLE

morne
  • 4,035
  • 9
  • 50
  • 96
  • Thanks for your anwer and yes this works if i wanted to style the parent of the input box. So partially this is true however would it also be possible to style ANY class? – Marco Geertsma Sep 12 '14 at 11:56
  • Just made a change to style the `INPUT` itself. You could add and remove any class you like basically. And style that class to a specific style that you want. – morne Sep 12 '14 at 11:57
1

If the element css which you want to change is sibling, you can use like this,

        <div class="container">
           <input class="myAwesomeInputBox">
           <div className="dls-sibling">
        </div>

        
  .myAwesomeInputBox:focus ~.dls-sibling {
        &::before {
            transform: scale(1);
            border-color:red;
       
  }
}
Vijay122
  • 884
  • 8
  • 12