Skip to content
Advertisement

SVG stroke animation not working in Safari

My JS code goes over each path, and adds a stroke-dasharray and stroke-dashoffset according to path length:

setTimeout(() => {
    const $paths = document.getElementsByTagName('path');
    for (const path of $paths) {
        const totalLength = path.getTotalLength();
        path.style.strokeDashoffset = totalLength;
        path.style.strokeDasharray = totalLength;
    }
}, 300);

Then, My CSS just animates the dashoffset to 0, while lowering the stroke opacity and raising the fill opacity:

.character path {
    fill-opacity: 0;
    stroke-opacity: 1;
    stroke-width: 2px;
    stroke: white;
    -webkit-animation: path 4s linear 1s both;
            animation: path 4s linear 1s both;
}

@keyframes path {
    70% {
        fill-opacity: 0;
    }

    80% {
        stroke-dashoffset: 0;
        stroke-opacity: 1;
        
    }

    100% {
        stroke-opacity: 0;
        stroke-dashoffset: 0;
        fill-opacity: 1;
    }
}

This works perfectly in Chrome – the animation shows the paths being drawn, but in Safari, the paths just show up without any animation.
I tried prefixing but it doesn’t work.
EDIT: This is somehow related to the timeout I set, I just added it to the code of the question. I have to add that timeout because the svg is loaded dynamically. Here is a Fiddle showing the problem (works in Chrome, not in Safari), thanks @kaiido.

Answer

I solved this by doing two things:

  1. Put the animation property in the JS as well
  2. I found out that Safari doesn’t handle animations in setTimeout if the animation delay is larger than the timeout. So I lowered the delay to 200ms.

Updated JS:

setTimeout(() => {
    const $paths = document.getElementsByTagName('path');
    for (const path of $paths) {
        const totalLength = path.getTotalLength();
        path.style.strokeDashoffset = totalLength;
        path.style.strokeDasharray = totalLength;
        path.style.animation = 'path 4s linear 0.2s both';
  };
}, 300);

Working Fiddle

Advertisement