Change color of SVG when hover on parent element

Viewed 6057

I have menu. Each menu item has SVG image and text. SVG is embedded using <object>

<ul id="menu-content" class="menu-content collapse out">
  <li id="calculator">
    <a href="#">
      <tr>
        <td>
          <object type="image/svg+xml" data="assets/calculator.svg">
          </object>
        </td>
        <td class="menu-option">
          <span class="menu-option">
            Pricing & Services
          </span>
        </td>
      </tr>
    </a>
  </li>
  .....
</ul>

When I hover on menu item, background color of this item changes. But I also need to change SVG color. For now I know how to change SVG color when you hover exactly on it. But what to do when I hover on parent element.

5 Answers

I know i'm late but google sent me here for the same problem and i didnt find the solution so here is what I used (hope it help someone):

CSS:

.roundedArea:hover > svg *,
.roundedArea:hover {
  background-color: yellowgreen;
  fill: #FFFFFF;
}

HTML structure:

    <a class="roundedArea">
      <svg>
          *i removed the svg code for reading comprehension*
      </svg>
    </a>

Preview (when you hover the area it change the parent color with green and fill the svg with white) :

enter image description here

I just made a snippet, here it is : https://codepen.io/Demky/pen/XQQWyj

When you're working with svg, you can change colors using fill and stroke properties instead of regular background-color and color. For example:

li:hover {
  background-color: yellow;
}

li:hover circle {
  fill: violet;
  stroke: blue;
}
<ul id="menu-content" class="menu-content collapse out">
  <li id="calculator">
    <a href="#">
      <tr>
        <td>
          <svg>
            <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
          </svg>
        </td>
        <td class="menu-option">
          <span class="menu-option">
            Pricing & Services
          </span>
        </td>
      </tr>
    </a>
  </li>
 </ul>

Just add a hover listener to the parent element.

var parent = document.querySelector('.parent')
parent.addEventListener('mouseover', function(){
  parent.children[0].style.backgroundColor = 'black';
})
parent.addEventListener('mouseout', function(){
  parent.children[0].style.backgroundColor = 'white';
})
.pretendThisIsTheSVG {\
  background-color: white;
  width:50px;
  height:50px;
  border:1px solid black;
}

.parent {
  width:100px;
  height:100px;
  border:1px solid red;
}
<div class="parent">
  <div class="pretendThisIsTheSVG">
  
  </div>
<div>

You can not do this using css as stylesheet rules don't apply cross documents. By this can be done using javascript as below:

var parent = document.querySelector('li')
parent.addEventListener('mouseover', function(event){
  var svg = event.target.querySelector('object').contentDocument;
  var styleElement = svg.createElementNS("http://www.w3.org/2000/svg", "style");
  styleElement.textContent = "svg * { fill: #fff }"; // add whatever you need here
  svg.appendChild(styleElement);
});

So what I did is: 1) Made sure the application is being run on server (I use http server) 2) In index.html I gave id to SVG (id='hat') and parent element (id='m-i-hat'):

<li id="m-i-hat">
  <a href="#" class="menu-item">
    <object class="menu-icon" id="hat" type="image/svg+xml" data="assets/hat.svg">
    </object>

3) in Index.js :

$(document).ready(function() {
var hat = document.getElementById("hat");
var parent_hat = document.getElementById("m-i-hat")

// It's important to add an load event listener to the object,
// as it will load the svg doc asynchronously
hat.addEventListener("load",function(){
  // get the inner DOM of image
  var svgDoc = hat.contentDocument;
  // get the inner element by id (in my svg I have a path i need to change with 
  //id='Hat')
  var area = svgDoc.getElementById("Hat");
  // add behaviour
  parent_hat.addEventListener("mouseover",function(){
   area.style.fill = '#fff'
  });
  parent_hat.addEventListener('mouseout', function(){
   area.style.fill = '#50BC99'
  })
});
Related