Reputation: 297
In a React application, I'm returning an SVG tag from a component. The SVG consists of a ring, and groups of elements positioned around it. Each group contains a shape (circle or rect) and a path depicting a number overlaying and identifying the shape.
For a minimum working example: https://codepen.io/notthelewis/pen/gOGRZQQ
Each group can be either active or inactive. In the inactive state, I want the background colour of the shape to change on hover , but I want the path's fill to stay the same colour. Current behaviour of the codepen works when hovering over the shape itself, but reverts when hovering over the path (number) element, which is inside the shape; meaning that the fill of the shape returns to default rather than the chosen hover colour.
In looking around, I tried a few solutions, but could not get the selectors to perform quite how I want.
To surmise:
.inactive path:hover
should somehow target: is(rect, circle)
contained in the same group.inactive path
's stroke property should remain unaffected.I've tried the following (to no avail!):
.inactive ~ path:hover {
fill: red;
}
.inactive path:hover ~ {
fill: red;
}
.inactive path:hover+rect {
fill: red;
}
.inactive :is(rect, circle)+path:hover {
fill: red;
}
I did find the has
selector, but it doesn't appear to be adopted anywhere meaningful...
https://caniuse.com/css-has
And the has
selector is also mentioned alongside the general successor
selector answer provided in this SO question:
Is there a "previous sibling" selector?
Upvotes: 0
Views: 86
Reputation: 155290
Put the :hover
on the <g>
, not a descendant of <g>
:
g.inactive:hover > rect,
g.inactive:hover > circle {
fill: grey;
}
Also, replace the huge <path>
elements that are being used to represent text with <text>
elements:
Before:
<svg width="468" height="304" viewBox="0 0 468 304" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Sensors">
<circle id="Sensor Ring" cx="228" cy="154" r="149" stroke="black" strokeWidth="2"/>
<g id="6" class='inactive'>
<rect id="6_sensor" x="80" y="203" width="20" height="20" fill="white" stroke="black" strokeWidth="2"/>
<path id="6_tag" d="M86.9941 213.561C86.9941 211.866 87.3516 210.604 88.0664 209.776C88.7852 208.948 89.8594 208.534 91.2891 208.534C91.7773 208.534 92.1602 208.563 92.4375 208.622V210.069C92.0898 209.991 91.7461 209.952 91.4062 209.952C90.7852 209.952 90.2773 210.046 89.8828 210.233C89.4922 210.421 89.1992 210.698 89.0039 211.065C88.8086 211.432 88.6934 211.954 88.6582 212.63H88.7344C89.1211 211.966 89.7402 211.634 90.5918 211.634C91.3574 211.634 91.957 211.874 92.3906 212.354C92.8242 212.835 93.041 213.499 93.041 214.346C93.041 215.261 92.7832 215.985 92.2676 216.52C91.752 217.052 91.0371 217.317 90.123 217.317C89.4902 217.317 88.9375 217.171 88.4648 216.878C87.9961 216.585 87.6328 216.157 87.375 215.595C87.1211 215.032 86.9941 214.354 86.9941 213.561ZM90.0879 215.87C90.4746 215.87 90.7715 215.741 90.9785 215.483C91.1855 215.221 91.2891 214.85 91.2891 214.37C91.2891 213.952 91.1914 213.624 90.9961 213.386C90.8047 213.143 90.5137 213.022 90.123 213.022C89.7559 213.022 89.4414 213.141 89.1797 213.38C88.9219 213.618 88.793 213.895 88.793 214.212C88.793 214.677 88.9141 215.069 89.1562 215.389C89.4023 215.71 89.7129 215.87 90.0879 215.87Z" fill="black"/>
</g>
After:
<svg width="468" height="304" viewBox="0 0 468 304" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Sensors">
<circle id="Sensor Ring" cx="228" cy="154" r="149" stroke="black" strokeWidth="2"/>
<g id="6" class='inactive'>
<rect id="6_sensor" x="80" y="203" width="20" height="20" fill="white" stroke="black" strokeWidth="2"/>
<text>6</text>
</g>
(You'll need to set font-size though).
Upvotes: 1