MadGrip
MadGrip

Reputation: 471

How to change color of element when sibling is focused?

Im trying to change a color of little svg that I have in my input, when the input is focused, but I dont know how to target it properly. In devtools I can either change color of label or svg directly, both of them work.

<form action="" className="search-bar input-wrapper" onSubmit={(e) => handleSubmit(e)}>
        <input
            type="text"
            className="input"
            id="search-bar-input"
            placeholder="Search..."
            value={searchbar}
            onChange={(e) => handleChange(e)}
            onKeyDown={(e) => handleKeyDown(e)}
        />

        <label id="input-label" htmlFor="search-bar-input">
            <VscSearch id="input-icon" className="input-icon" />
        </label>
    </form>

Stuff I tried and didnt work:

#search-bar-input:focus ~ #input {
color: red;
}

#search-bar-input:focus + #input {
color: red;
}

#search-bar-input:focus ~ #input-icon {
    color: blue;
}

#search-bar-input:focus + #input-icon {
    color: blue;
}

.search-bar {
    &:focus {
        #input-label {
            color: yellow;
        }
        #input-label {
            svg {
                color: orange;
            }
        }

        #input-icon {
            color: green;
        }
    }
}

I can write this in sass or CSS, it doesnt matter.

Upvotes: 1

Views: 1193

Answers (1)

Arkellys
Arkellys

Reputation: 7790

You can either use the adjacent sibling combinator (+) or the general sibling combinator (~):

#search-bar-input:focus + #input-label-1 {
   /* Only works if #input-label-1 immediately follows #search-bar-input */
   color: red;
}

#search-bar-input:focus ~ #input-label-2 {
   color: blue;
}
<input
   type="text"
   id="search-bar-input"
   placeholder="Search..."
/>

<label id="input-label-1">
   <i>Red</i>
</label>

<label id="input-label-2">
   <i>Blue</i>
</label>


As for what you tried:

#search-bar-input:focus ~ #input
#search-bar-input:focus + #input

These can't work because you don't have any id named #input.

#search-bar-input:focus ~ #input-icon

The general sibling combinator requires both elements to share same parent.

#search-bar-input:focus + #input-icon

The adjacent sibling combinator requires your targeted element to immediately follows the first element.


And finally, your compiled SCSS would be:

.search-bar:focus #input-label {
  color: yellow;
}

.search-bar:focus #input-label svg {
  color: orange;
}

.search-bar:focus #input-icon {
  color: green;
}

Since .search-bar doesn't get the focus of the input, it can't work using the pseudo-class :focus. However, it will work with :focus-within:

.search-bar:focus-within #input-label {
  color: yellow;
}
<form class="search-bar">
   <input
      type="text"
      id="search-bar-input"
      placeholder="Search..."
   />

   <label id="input-label">
      <i>Yellow</i>
   </label>
</form>

Note that this pseudo-class is not supported by IE.

Upvotes: 4

Related Questions