GFL GFL - 2 months ago 9
CSS Question

Using sibling combinator with svg and :focus

I just learned about the sibling combinator in CSS and I'm trying to shift some of JavaScript operations into CSS but I'm having difficulty.

<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="m64 50-4-8h-6v-4c0-1.1-0.9-2-2-2h-18c-1.1 0-2 0.9-2 2v16l2 2h2.536c-0.341 0.588-0.536 1.271-0.536 2 0 2.209 1.791 4 4 4s4-1.791 4-4c0-0.729-0.196-1.412-0.536-2h11.073c-0.341 0.588-0.537 1.271-0.537 2 0 2.209 1.791 4 4 4s4-1.791 4-4c0-0.729-0.196-1.412-0.537-2h2.537v-6zm-10 0v-6h4.146l3 6h-7.146z"/></svg>
<div><input type="text"></div>
<div><input type="text"></div>
<div><input type="text"></div>
</div>


I'm able to change the color of my svg image with:

path{fill:#f00}


However, I'd only like to change the color if an input in .box is focused.

.box svg path~.box div input:focus{fill:#f00}


Since they are not directly siblings, I used prefixes to bring them to the same level.

What am I doing wrong?

Answer

As mentioned here:

The ~ combinator separates two selectors and matches the second element only if it is preceded by the first, and both share a common parent.

So the involved elements must have the same parent. This should not be confused with "same ancestor". .box is an ancestor of path and input:focus but is not either's parent.

Because of this, you usually don't specify the whole CSS "path" on the right. This also means you can't pair an element inside svg with an element outside.

You also have the order backwards. Assuming it worked at all, fill would be applied to input:focus.

Moving things around to make it work and taking advantage of some other tricks gives something like this:

input {
  display:block;
}
.box input:focus ~ svg {
  fill:#f00;
}
<div class="box">
  <input type="text">
  <input type="text">
  <input type="text">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="m64 50-4-8h-6v-4c0-1.1-0.9-2-2-2h-18c-1.1 0-2 0.9-2 2v16l2 2h2.536c-0.341 0.588-0.536 1.271-0.536 2 0 2.209 1.791 4 4 4s4-1.791 4-4c0-0.729-0.196-1.412-0.536-2h11.073c-0.341 0.588-0.537 1.271-0.537 2 0 2.209 1.791 4 4 4s4-1.791 4-4c0-0.729-0.196-1.412-0.537-2h2.537v-6zm-10 0v-6h4.146l3 6h-7.146z"/></svg>
</div>