Why Doesn't This CSS Transition Work On SVG Inside an Anchor
Asked Answered
P

4

7

I'm trying to transition the fill and path of an embedded SVG object, however this doesn't seem to work (Code Pen here):

The SVG:

<a class="simple-link svg-link" href="">
  Some Text
  <svg version="1.1" id="next-page-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
      viewBox="0 0 25 25" enable-background="new 0 0 25 25" xml:space="preserve" preserveAspectRatio="xMinYMin meet">
    <circle class="the-background" cx="12.5" cy="12.5" r="12.5"/>
    <g>
      <path class="the-icon"  d="M16.088,11.421l-3.404,3.362l-3.418-3.362v-1.204l3.418,3.444l3.404-3.444V11.421z"/>
     </g>
  </svg>
</a>

The Sass:

a
{
  width:200px;
  height:200px;
  overflow: hidden;

  @include transition(color, 1s);
  @include transition(background, 1s);

  svg
  {
    width:200px;
    height:200px;

    .the-background
    {
      @include transition(fill, 1s);
      fill: grey;
    }

    .the-icon
    {
      @include transition(fill, 2.5s);
    }
  }

  &:hover
  {
    color: red;
    background: black;
    .the-background
    {
      fill: black;
    }

    .the-icon
    {
      fill: red;
    } 

  }
}

Why don't the fills animate on hover?

Pantomimist answered 23/3, 2014 at 16:51 Comment(0)
Z
7

The reason why the transition doesn't work is because it is within a link.

To fix it, put the link inside of the SVG instead like this SO post suggests

OR

Make the SVG a sibling of the link and use the sibling selector

/* This goes within `a { ...` */
&:hover + svg { /* Or use ~ to select all */
  .the-background
  {
    fill: black;
  }

  .the-icon
  {
    fill: red;
  } 
}
Zygoma answered 23/3, 2014 at 19:2 Comment(1)
Thank you, thank you! Worked in Safari, unlike other things I tried.Psoriasis
E
17

The way I solved this problem was to place fill="currentColor" on the svg path element that I wanted to transition. Then I added color and transition properties to the surrounding anchor tag and performed the CSS transition on the anchor tag instead of the svg path itself. Below is a very stripped down example:

HTML:

<a>
    <svg>
        <path fill="currentColor" />
    </svg>
</a>

SCSS:

a { color: black; transition: color .2s linear;
    &:hover { color: white; } }
Elysian answered 26/7, 2016 at 19:3 Comment(0)
Z
7

The reason why the transition doesn't work is because it is within a link.

To fix it, put the link inside of the SVG instead like this SO post suggests

OR

Make the SVG a sibling of the link and use the sibling selector

/* This goes within `a { ...` */
&:hover + svg { /* Or use ~ to select all */
  .the-background
  {
    fill: black;
  }

  .the-icon
  {
    fill: red;
  } 
}
Zygoma answered 23/3, 2014 at 19:2 Comment(1)
Thank you, thank you! Worked in Safari, unlike other things I tried.Psoriasis
T
6

I just discovered that in order to transition an svg fill within an anchor element, it only works using rgba color codes. I haven't researched why that is, but it's working on my projects - here's an example: http://rawesome.leveragenewagemedia.com/ (hover the social media icons).

Here's the SASS I'm using:

.icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  fill: rgba(0,0,0,.2);
  -webkit-transition: fill .5s;
  -moz-transition: fill .5s;
  -ms-transition: fill .5s;
  -o-transition: fill .5s;
  transition: fill .5s;

  &:hover {
    fill: rgba(0,0,0,.5);
  }
}
Talamantes answered 26/4, 2014 at 16:43 Comment(2)
I just tried this and it appears it only works for opacity. Using different colors still won't transition with this method.Traitorous
This solution definitely works for transitioning between color states. Thanks for posting this!Alienor
R
0

I have to contradict the marked answer because, at least at this point in time, the statement, svg transitioning and animating wouldn't work inside an anchor tag is simply not true.

Working example:

    <!doctype html>
    <html>
        <body>
            <a>
                <svg width="100%" height="100%" viewBox="0 0 800 600" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
                    <path d="M211.281,336.939C211.281,336.939 285.671,363.039 355.793,360.727C425.915,358.414 439.329,333.635 491.159,336.939C491.159,336.939 494.646,428.533 356.402,433.741C219.839,438.885 216.224,360.378 211.281,336.939Z" style="stroke:#000;stroke-width:46.14px;"/>
                    <path d="M244.207,187.195C259.451,224.852 289.939,244.499 311.28,197.019" style="fill:none;stroke:#000;stroke-width:46.14px;"/>
                    <path d="M383.841,219.954C406.402,233.327 447.866,257.844 461.89,198.78" style="fill:none;stroke:#000;stroke-width:46.14px;"/>
                </svg>
            </a>
        </body>
        <style>
        
            svg>path{
                transition: 1s;
            }
            svg path:nth-of-type(1){
                fill:#ffe7cb;
            }
            svg:hover>path:nth-of-type(1){
                d: path("M211.89,300C211.89,300 286.281,348.171 356.402,343.902C426.524,339.634 439.939,293.902 491.768,300C491.768,300 495.256,469.047 357.012,478.659C220.449,488.153 216.834,343.258 211.89,300Z");
                fill:white;
            }
            svg:hover>path:nth-of-type(2){
                d: path("M244.207,187.195C259.451,173.171 289.939,165.854 311.28,183.537");
            }
            svg:hover>path:nth-of-type(3){
                d: path("M383.841,187.195C406.402,179.878 447.866,166.463 461.89,198.78");
            }
            a{
                height: 300px;
                width: 400px;
                display: block;
            }
        </style>
    </html>
Ruddy answered 9/2, 2023 at 18:28 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.