Skip to content
Advertisement

Css animation has strange delay when animating two SVG properties

As the title said when I tried to animate the stroke-dashoffset and fill at the same time. It has this strange unwanted 3-second delay, but I have both of the animated properties are in one keyframe as shown below

svg {
  background-color: black;
  stroke-dasharray: 1800;
  fill: #fff;
  stroke: #fff;
  opacity: 10;
  animation: reveal 10s cubic-bezier(0, 0.23, 1, 0.1);
  animation-delay: 0;
  max-width: min(calc(100vw - 10rem), 40rem);
}
@keyframes reveal {
  0% {
    fill: none;
    stroke-dashoffset: 1800;
  }
  80% {
    fill: rgba(255, 255, 255, 0);
  }
  100% {
    fill: rgba(255, 255, 255, 1);
    stroke-dashoffset: 0;
  }
}
<svg
      id="Layer_1"
      data-name="Layer 1"
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 314.41 79.8"
    >
      <defs>
        <style>
          .cls-1 {
            font-size: 76px;
            font-family: BebasNeue-Regular, Bebas Neue;
          }
          .cls-2 {
            letter-spacing: 0em;
          }
          .cls-3 {
            letter-spacing: 0em;
          }
        </style>
      </defs>
      <text class="cls-1" transform="translate(0 64.6)">
        Hel
        <tspan class="cls-2" x="85.65" y="0">l</tspan>
        <tspan class="cls-3" x="111.49" y="0">o World</tspan>
      </text>
    </svg>

I have attempted research by visiting the following URL:

  1. Play multiple CSS animations at the same time

  2. CSS 3 weird animation delay

But still, I haven’t got any idea to solve my problem, on the right is my code on jsfiddle https://jsfiddle.net/ju781mb9/

PS. The video is only for placeholder so you got an idea of the website and i also slow the animation down

Advertisement

Answer

The way you write the @keyframes rule, it seems you expect the stroke-dashoffset to start at the begining of the animation duration, and to end at its end. But in fact, you have absolutely no control about that the way your code is structured. You write stroke-dasharray: 1800 and assume that 1800px is the total stroke length.

  • Stroke length for glyphs in a text is the length of the outline for each individual glyph. Each glyph has a different stroke length.
  • If a glyph consists of multiple subpaths, like the letter “o” consists of an outer and an inner line, the stroke-dasharray is defined for each of them individually. You then have multiple animated lengths in one combined stroke.
  • You give a non-standard font-family, but do not include a web font source. This means everyone who has not, by chance, installed the exact font you assume, will see a text in a different replacement font with different stroke lengths.
  • You define a fallback font. Both fonts will have different stroke lengths.

There is only one way to get out of this dilemma and gain control of the stroke lengths and subsequent animation timings: use a vector grafics editor to convert the text into paths. (Adobe Illustrator, which you seem to use, can do that.) Remember to set an aria-label attribute to anotate the enclosing <g> element with the text it originally represented.

SVG <path> elements have a pathLength attribute where you can simply overrride the measured stroke length with a make-believe one. If you then use that value for your stroke-dasharray property, the animation will run as if the correct stroke length had been used. The following code will show a stroke along exactly the half of the path length:

    <path style="stroke-dasharray:100;stroke-dashoffset:-50" 
          pathLength="100" 
          d="M 125.2,25.3 H 131.7 V 80 H 125.2 Z" />

Note the negative number for stroke-dashoffset. (I am going to bail out on describing the complicated reasons here, they could fill a whole tutorial.)

svg {
  background-color:black;
}

.label path {
  fill: white;
  stroke: white;
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  animation: reveal 10s cubic-bezier(0, 0.23, 1, 0.1);
}

@keyframes reveal {
  0% {
    fill: none;
    stroke-dashoffset: -100;
  }
  80% {
    fill: rgba(255, 255, 255, 0);
  }
  100% {
    fill: rgba(255, 255, 255, 1);
    stroke-dashoffset: 0;
  }
}
<svg viewBox="0 0 450 100">
  <g class="label" aria-label="Hello World" style="fill:none;stroke:#ffffff">
    <path pathLength="100" d="M 27.07,27.51 H 34.17 V 49.03 H 59.97 V 27.51 H 67.07 V 80 H 59.97 V 55 H 34.17 V 80 H 27.07 Z" />
    <path pathLength="100" d="M 114.6,58.7 V 61.86 H 84.86 Q 85.29,68.54 88.87,72.05 92.49,75.54 98.93,75.54 102.7,75.54 106.1,74.62 109.6,73.71 113.1,71.88 V 78 Q 109.6,79.47 106,80.25 102.3,81.02 98.54,81.02 89.12,81.02 83.6,75.54 78.11,70.05 78.11,60.7 78.11,51.03 83.32,45.37 88.55,39.68 97.41,39.68 105.4,39.68 110,44.81 114.6,49.91 114.6,58.7 Z M 108.1,56.8 Q 108.1,51.49 105.1,48.32 102.3,45.16 97.48,45.16 92.07,45.16 88.8,48.22 85.57,51.28 85.07,56.83 Z" />
    <path pathLength="100" d="M 125.2,25.3 H 131.7 V 80 H 125.2 Z" />
    <path pathLength="100" d="M 145.2,25.3 H 151.7 V 80 H 145.2 Z" />
    <path pathLength="100" d="M 180.4,45.16 Q 175.2,45.16 172.2,49.24 169.2,53.28 169.2,60.35 169.2,67.41 172.2,71.49 175.2,75.54 180.4,75.54 185.6,75.54 188.6,71.46 191.6,67.38 191.6,60.35 191.6,53.35 188.6,49.27 185.6,45.16 180.4,45.16 Z M 180.4,39.68 Q 188.9,39.68 193.7,45.16 198.5,50.64 198.5,60.35 198.5,70.02 193.7,75.54 188.9,81.02 180.4,81.02 171.9,81.02 167.1,75.54 162.3,70.02 162.3,60.35 162.3,50.64 167.1,45.16 171.9,39.68 180.4,39.68 Z" />
    <path pathLength="100" d="M 227.7,27.51 H 234.9 L 245.9,71.88 256.9,27.51 H 264.9 L 275.9,71.88 286.9,27.51 H 294.1 L 281,80 H 272 L 261,34.44 249.8,80 H 240.9 Z" />
    <path pathLength="100" d="M 314.3,45.16 Q 309.1,45.16 306.1,49.24 303,53.28 303,60.35 303,67.41 306,71.49 309.1,75.54 314.3,75.54 319.5,75.54 322.5,71.46 325.5,67.38 325.5,60.35 325.5,53.35 322.5,49.27 319.5,45.16 314.3,45.16 Z M 314.3,39.68 Q 322.7,39.68 327.5,45.16 332.4,50.64 332.4,60.35 332.4,70.02 327.5,75.54 322.7,81.02 314.3,81.02 305.8,81.02 301,75.54 296.2,70.02 296.2,60.35 296.2,50.64 301,45.16 305.8,39.68 314.3,39.68 Z" />
    <path pathLength="100" d="M 365.9,46.67 Q 364.8,46.04 363.5,45.76 362.2,45.44 360.7,45.44 355.2,45.44 352.2,49.03 349.3,52.58 349.3,59.26 V 80 H 342.8 V 40.63 H 349.3 V 46.74 Q 351.3,43.16 354.6,41.43 357.9,39.68 362.6,39.68 363.2,39.68 364,39.78 364.8,39.85 365.8,40.03 Z" />
    <path pathLength="100" d="M 372.7,25.3 H 379.2 V 80 H 372.7 Z" />
    <path pathLength="100" d="M 418.6,46.6 V 25.3 H 425.1 V 80 H 418.6 V 74.09 Q 416.6,77.61 413.4,79.33 410.3,81.02 406,81.02 398.8,81.02 394.3,75.32 389.9,69.63 389.9,60.35 389.9,51.07 394.3,45.37 398.8,39.68 406,39.68 410.3,39.68 413.4,41.4 416.6,43.09 418.6,46.6 Z M 396.6,60.35 Q 396.6,67.48 399.5,71.56 402.4,75.61 407.6,75.61 412.7,75.61 415.6,71.56 418.6,67.48 418.6,60.35 418.6,53.21 415.6,49.17 412.7,45.09 407.6,45.09 402.4,45.09 399.5,49.17 396.6,53.21 396.6,60.35 Z" />
  </g>
</svg>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement