CSS generic selector not working with SVG

ghz 8months ago ⋅ 90 views

If I have this HTML

<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <g id="repeat">
    <path fill="currentColor"
      d="M20.3 13.43a1 1 0 0 0-1.25.65A7.14 7.14 0 0 1 12.18 19A7.1 7.1 0 0 1 5 12a7.1 7.1 0 0 1 7.18-7a7.26 7.26 0 0 1 4.65 1.67l-2.17-.36a1 1 0 0 0-1.15.83a1 1 0 0 0 .83 1.15l4.24.7h.17a1 1 0 0 0 .34-.06a.33.33 0 0 0 .1-.06a.78.78 0 0 0 .2-.11l.09-.11c0-.05.09-.09.13-.15s0-.1.05-.14a1.34 1.34 0 0 0 .07-.18l.75-4a1 1 0 0 0-2-.38l-.27 1.45A9.21 9.21 0 0 0 12.18 3A9.1 9.1 0 0 0 3 12a9.1 9.1 0 0 0 9.18 9A9.12 9.12 0 0 0 21 14.68a1 1 0 0 0-.7-1.25Z" />
  </g>
</svg>
<svg id="btnRepeat" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="button">
  <use href="#repeat"></use>
</svg>

and this CSS

:root {
  --norm-colour: green;
  --high-colour: red;
}

#btnRepeat {
  position: absolute;
  width: 15%;
  color: var(--norm-colour);
}

#btnRepeat:hover {
  color: var(--high-colour);
  cursor: pointer;
}

The svg colour is correct and changes on hover as expected.

If I change the selector from #btnRepeat:hover to a "generic" form of svg[id^="btn"]:hover the colour change on hover does not occur (though the cursor changes.) Why is it that the generic form fails?

Answers

The reason the generic selector svg[id^="btn"]:hover fails to apply the hover color change is due to the specificity of the selector and how it targets the use element.

When you use #btnRepeat:hover, it directly targets the svg element with the id btnRepeat, and it works because the svg element itself is being hovered over.

However, when you use the generic selector svg[id^="btn"]:hover, it targets the svg elements whose id starts with "btn" and then applies the hover effect. But in your case, the use element is what's being hovered over, not the svg element with the id "btnRepeat".

To make the generic selector work, you should target the use element itself. You can achieve this by modifying the selector to include the use element:

svg[id^="btn"]:hover use {
  color: var(--high-colour);
}

This selector targets the use element within any svg element whose id starts with "btn" and applies the hover color change.