2

From this example, I am trying to dim (i.e. reduce opacity) non-hover elements of a html page.

The code below works only for non-overlapping elements. However, if the page contains an element that overlaps in the background, and that I do not want any effect on it when hover (e.g. green square below), the "hoverable" elements of interest (e.g. red circle and blue rectangle below) are dimmed when they are not hover, but when the cursor is still on the background shape.

In other words:

. green square: not "hoverable" (should not have any effect when hover)

. red circle: "hoverable" (i.e. dim all other elements when hover, i.e. blue rectangle and green square)

. blue rectangle: "hoverable" (i.e. dim all other elements when hover, i.e. red circle and green square)

How could I skip dimming all elements when hover the green square?

.parent:hover .child {
  opacity: 0.2;
  transition: all .3s;
}

.parent .child:hover {
  opacity: 1;
  transition: all .3s;
}
<svg width="250" height="250">
  <g class="parent">
    <rect x="0" y="0" width="150" height="150" fill="green"/>
      
    <g class="child">
      <circle cx="30" cy="45" r="25" fill="red"/>
    </g>
    
    <g class="child">
      <rect x="60" y="80" width="60" height="30" fill="blue"/>
    </g>
  
  </g>
</svg>
6PO0222
  • 131
  • 7

3 Answers3

2

Your only hope (I think) is to use pointer-events: none.

But this will avoid any pointer interaction with the element

.parent:hover .child {
  opacity: 0.2;
  transition: all .3s;
}

.parent .child:hover {
  opacity: 1;
  transition: all .3s;
}

.nohover {
  pointer-events: none;
}
<svg width="250" height="250">
  <g class="parent">
    <rect class="nohover" x="0" y="0" width="150" height="150" fill="green"/>
      
    <g class="child">
      <circle cx="30" cy="45" r="25" fill="red"/>
    </g>
    
    <g class="child">
      <rect x="60" y="80" width="60" height="30" fill="blue"/>
    </g>
  
  </g>
</svg>
vals
  • 61,425
  • 11
  • 89
  • 138
1

The easiest option is to move your filled rectangle outside of the .parent, at which point the existing CSS will work as intended as the .parents opacity is not being applied to the green background.

.parent:hover .child {
  opacity: 0.2;
  transition: all .3s;
}

.parent .child:hover {
  opacity: 1;
  transition: all .3s;
}
<svg width="250" height="250">

  <rect x="0" y="0" width="150" height="150" fill="green"/>
  
  <g class="parent">
    
    <g class="child">
      <circle cx="30" cy="45" r="25" fill="red"/>
    </g>
    
    <g class="child">
      <rect x="60" y="80" width="60" height="30" fill="blue"/>
    </g>
  
  </g>
</svg>
DBS
  • 9,110
  • 4
  • 35
  • 53
1

Try like this:

.parent:hover .child {
  opacity: 0.2;
  transition: all .3s;
}

.parent:hover rect:hover ~.child,
.parent .child:hover {
  opacity: 1;
  transition: all .3s;
}
<svg width="250" height="250">
  <g class="parent">
    <rect x="0" y="0" width="150" height="150" fill="green"/>
      
    <g class="child">
      <circle cx="30" cy="45" r="25" fill="red"/>
    </g>
    
    <g class="child">
      <rect x="60" y="80" width="60" height="30" fill="blue"/>
    </g>
  
  </g>
</svg>

As the rect element is before the .child elements, it is possible to check for its :hover in addition to .parent:hover and then style the .child elements accordingly.

sbgib
  • 5,580
  • 3
  • 19
  • 26