Search code examples
pythonhtmlsvghyperlink

Persistent color change after visiting embedded svg graphic link


I have a svg graphic that links to various survey pages. The svg paths are embedded between <a href> and </a> to link the graphic to a survey url. Hover works fine. Each #path_xx is a unique survey. After the user completes a survey and is returned to the selection page I want the svg element just visited to change color to indicate that survey has been completed. I have tried several css styles but none have worked:

  #path_cm:hover, #path_rm:hover, #path_is:hover, #path_bc:hover, #path_hr:hover, #path_ict:hover, 
  #path_sc:hover, #path_fa:hover, #path_env:hover, #path_hs:hover, #path_em:hover, #path_center:hover {
    opacity: .5;
    stroke: blue;
    stroke-opacity: 1;
    stroke-width: 5
  }

  #path_cm:visited, #path_rm:visited, #path_is:visited, #path_bc:visited, #path_hr:visited, #path_ict:visited, 
  #path_sc:visited, #path_fa:visited, #path_env:visited, #path_hs:visited, #path_em:visited, #path_center:visited {
    color: red;
    opacity: .5;
  }

  link:visited svg path{
    color: red;
    opacity: .5;
  }

Here is the applicable template:

            <a href='{% url 'introduction' %}'>
            <path id="path_bc" fill="#027aff" stroke="none" opacity="0" d="M 210.919983 80.78241 C 210.919983 61.452454 195.249954 45.78241 175.920013 45.78241 C 156.590012 45.78241 140.919983 61.452454 140.919983 80.78241 C 140.919983 100.112366 156.590012 115.78241 175.920013 115.78241 C 195.249954 115.78241 210.919983 100.112366 210.919983 80.78241 Z"/>
            </a>

Tried several variations on style; including link:visited svg path_bc and link:visited svg #path_bc.


Solution

  • When having an SVG anchor element you need to specify the namespace of that element, like it is described here: @namespace (they use the SVG anchor case as the example).

    So you have two options. Either the anchor element is an HTML anchor, and in that case :visited works out of the box, or you specify the SVG namespace so that you can refer to the SVG anchor element. Both versions are shown in this example:

    The JavaScript is just for changing the URL, so that each time the example run, you will not have visited the page. Hold down the Ctrl key when you click an anchor

    // Changing the URL for all anchor elements
    // for testing the pseudo-class visited.
    let randomNumber = Math.random();
    document.querySelectorAll('a')
      .forEach(anchor => anchor.setAttribute('href', `/${randomNumber}`));
    @namespace svg url(http://www.w3.org/2000/svg);
    
    a:visited {
      color: red;
    }
    
    a:visited path {
      fill: red;
    }
    
    svg|a:visited path {
      fill: red;
    }
    <p>HTML anchor: <a href="/test" target="_blank">Test</a></p>
    <p>HTML anchor with child SVG:
      <a href="/test" target="_blank">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="100">
          <path fill="blue" stroke="none" d="M 100 0 A 100 100 0 1 0 101 0 Z" />
        </svg>
      </a>
    </p>
    <p>SVG with anchor element:
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="100">
        <a href="/test" target="_blank">
          <path fill="blue" stroke="none" d="M 100 0 A 100 100 0 1 0 101 0 Z" />
        </a>
      </svg>
    </p>