0

That is my stackblitz/codepen: https://stackblitz.com/edit/svgtest?file=index.tsx

When I hover over the svg rectangles the hover event triggers then because the parent svg element of the facade/roof, so I expected the border to be added to the svg element, but its not! Instead all the svg children elements own has that border set.

Why this?

OnMouseOver is registred for the svg element as you can see here:

   return <svg
      onMouseOver={e => this.props.currentMounting.onMountingHoveredOver(e)}
      onMouseOut={e => this.props.currentMounting.onMountingHoveredOut(e)}
      onClick={e => this.props.currentMounting.onMountingSelected(e.currentTarget.id)}
      opacity={this.props.currentMounting.opacity}
      style={{ fill: 'red' }}
      id={this.props.currentMounting.id}>

      <rect x="0" y="0" height="60" width="60" />
      <rect x="70" y="0" height="60" width="60" />
    </svg>

But despite that all the rect elements display the border when I hover over them!?

Pascal
  • 12,265
  • 25
  • 103
  • 195

2 Answers2

0

Try to bring hover events and other needs to the "rect" level and not to the svg tag level :

Example :

return <svg
  onClick={e => this.props.currentMounting.onMountingSelected(e.currentTarget.id)}
  opacity={this.props.currentMounting.opacity}
  style={{ fill: 'red' }}
  id={this.props.currentMounting.id}>

  <rect onMouseOver={e => this.props.currentMounting.onMountingHoveredOver(e)}
  onMouseOut={e => this.props.currentMounting.onMountingHoveredOut(e)} x="0" y="0" height="60" width="60" />
  <rect onMouseOver={e => this.props.currentMounting.onMountingHoveredOver(e)}
  onMouseOut={e => this.props.currentMounting.onMountingHoveredOut(e)} x="70" y="0" height="60" width="60" />
</svg>
Gwen
  • 444
  • 2
  • 10
0

<svg> elements are container elements. That means that they are not painted themselves, but can group child elements that are graphics elements.

If you set a stroke style property on a container element, it has no effect. The only thing that happens is that it is inherited by the children, which, if they are graphics elements, will render the stroke.

If the <svg> was the outermost element directly embeded in a HTML element, you could set a border property. But as in your case they are nested in another <svg>, the only solution is to draw a rectangle (before the other rects) covering the whole viewport of the element and set a stroke on that:

<rect width="100%" height="100%"
     onMouseOver={e => this.props.currentMounting.onMountingHoveredOver(e)}
     onMouseOut={e => this.props.currentMounting.onMountingHoveredOut(e)}
     style={{ fill: 'none' }}>
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
ccprog
  • 20,308
  • 4
  • 27
  • 44