SVG Line Animation in Webflow: The Self-Drawing Line
The self-drawing SVG line, explained: how the stroke-dasharray and dashoffset trick works, real CSS code, clean single-path exports, and draw-on-scroll in Webflow.
To animate an SVG line so it draws itself, you trick the browser with the line's own dashes. Set stroke-dasharray to the length of the path so the dash equals the whole line, push it out of view with stroke-dashoffset, then animate the offset back to 0. The dash "slides" into place and the line appears to draw on. That's the entire trick. Everything else is plumbing.
Here's the minimal version, then we'll earn it.
<svg viewBox="0 0 200 100" fill="none">
<path class="draw" d="M10 90 C 40 10, 160 10, 190 90"
stroke="#111" stroke-width="3" stroke-linecap="round" />
</svg>
.draw {
stroke-dasharray: 300; /* roughly the path length */
stroke-dashoffset: 300; /* push the dash off the line */
animation: draw 1.6s ease forwards;
}
@keyframes draw {
to { stroke-dashoffset: 0; }
}
Load the page and the curve writes itself on, like an Etch A Sketch that finally learned cursive. I've shipped this effect on more Webflow heroes than I can count across seven years on the platform, and it still earns a "wait, how'd you do that" every time. Let me show you the how, the why, and the two or three places people faceplant.
Why the dash trick actually works
The magic isn't a special "draw" property. SVG doesn't have one. We're abusing dashed strokes.
stroke-dasharray controls a line's dash pattern: stroke-dasharray: 10 5 gives you a 10-unit dash, a 5-unit gap, repeating forever. Now imagine the dash is as long as the entire path and the gap is too. You get one solid line and one empty stretch the same length. stroke-dashoffset slides that pattern along the path. Offset it by the full length and the solid dash slides completely off-screen, leaving the gap — so the line looks invisible. Animate the offset back to 0 and the solid dash slides back into view from one end to the other.
Your eye reads "the line is being drawn." The browser knows it's just sliding a dash. Nobody tells the user. This is the kind of honest little lie good frontend is built on.
The one number you need is the path's real length. Eyeballing 300 works for a demo, but a wrong value means the line finishes early or never quite completes. Get it exactly with one line of JavaScript:
const path = document.querySelector('.draw');
const len = path.getTotalLength();
path.style.strokeDasharray = len;
path.style.strokeDashoffset = len;
getTotalLength() returns the precise path length in user units. Set both dasharray and dashoffset to it and your animation is pixel-honest at any size.
Get a clean single-path SVG first
Here's where most of these effects die before the CSS ever runs: a messy export. The draw trick wants one continuous <path>. Export an icon carelessly and you'll get a <g> stuffed with twelve sub-paths, a clip mask, and inline transforms — and animating that is like trying to sign your name with twelve pens taped together.
This is the same pattern I see in inherited Webflow projects everywhere. A site starts clean, then someone drops in a logo SVG from a Thursday rush, then another, and by month nine the markup is a junk drawer nobody wants to open. The fix is the same as it always is: clean it before you build on it.
In your vector tool, outline nothing, keep it as a stroke, and combine into a single path before export. A signature, a hand-drawn underline, a route on a map — anything that's one gesture in real life — should be one path in the file. Then run it through SVGO (or a free online optimizer) to strip the editor cruft. You want markup that reads like the snippet up top: a viewBox, a path, a d attribute, and not much else.
If your shape genuinely needs multiple paths, the trick still works — you just apply the dasharray/offset to each path and stagger their animation-delay. More on that below.
The CSS @keyframes version (full, correct)
For animation that runs on page load, pure CSS is the move. No JavaScript, no dependencies, no waiting on a library to parse.
.draw {
stroke-dasharray: 320;
stroke-dashoffset: 320;
animation: draw-on 2s cubic-bezier(0.65, 0, 0.35, 1) forwards;
}
@keyframes draw-on {
to { stroke-dashoffset: 0; }
}
Two things that punch above their weight here. forwards tells the animation to hold its final state instead of snapping back to invisible when it ends — forget it and your line draws on, then politely disappears. And the cubic-bezier easing gives the stroke a bit of acceleration so it feels like a hand moving, not a robot arm. ease is fine; a custom curve is better.
Multiple paths, staggered:
.draw path { stroke-dasharray: 320; stroke-dashoffset: 320;
animation: draw-on 1.2s ease forwards; }
.draw path:nth-child(2) { animation-delay: 0.4s; }
.draw path:nth-child(3) { animation-delay: 0.8s; }
Doing it in Webflow with scroll Interactions
CSS-on-load is great, but the effect that actually stops a scroll is draw-on-scroll — the line completing as the user arrives at it. In Webflow you've got two clean routes.
Route one — embed the CSS. Drop your SVG into an Embed element, paste the @keyframes from above into the same embed (or the page <head>), and it runs on load. Fastest to ship. The catch is it fires whether the user has scrolled to it or not.
Route two — Webflow Interactions, tied to scroll. This is the on-brand one. Add your SVG, then build a "While scrolling in view" interaction:
- Set the path's starting
stroke-dashoffsetto the full path length (use the Custom Properties / style panel, or a tiny embed that sets it). - Target
stroke-dashoffsetand animate it to0across the scroll range. - Map it to the element's scroll-into-view progress so the line draws as the section moves up the viewport.
Webflow's Interactions can't always reach SVG sub-properties through the GUI, which is one of those real limits worth knowing before you design into it — pretending Webflow does everything is how projects collapse. When the panel won't cooperate, a five-line embed setting strokeDashoffset against scroll position does the job and stays maintainable. For a deeper bench of tools and plugins that smooth this out, the 13 best Webflow resource sites for your next project is a good bookmark.
One discipline note: a self-drawing line is decoration. Decoration in service of one clear action is great; decoration that fights your call-to-action is just art with a hosting bill. Award-pretty heroes that don't tell the user what to do lose customers. Let the line point toward the button, not away from it.
Performance and accessibility (don't skip this)
Stroke animation is cheap — it's a single property changing — but two rules keep it from biting you.
Respect reduced motion. Some users get motion sick or just don't want the show. Honor that and skip straight to the finished line:
@media (prefers-reduced-motion: reduce) {
.draw { animation: none; stroke-dashoffset: 0; }
}
Don't tank your score for a flourish. We hand off builds at a 99/100 Lighthouse average, and an SVG animation should never be the thing that knocks a point off. Keep the SVG inline (no extra request), avoid animating dozens of paths at once, and let the GPU handle it. One clean path drawing on costs you nothing the user can feel.
FAQ
How do you animate an SVG line to draw itself?
Set stroke-dasharray and stroke-dashoffset to the path's full length to hide it, then animate stroke-dashoffset to 0. The dash slides into view and the line appears to draw on. Use path.getTotalLength() to get the exact length.
What does stroke-dashoffset actually do? It shifts a stroke's dash pattern along the path. When your dash is as long as the whole line, offsetting by that length slides the visible dash completely off, making the line look gone. Animating the offset back to zero brings it back, one end to the other.
Do I need JavaScript for SVG line animation?
No. Pure CSS @keyframes animating stroke-dashoffset covers load-triggered effects with zero JS. You only need a line of JavaScript if you want getTotalLength() to set an exact dash value, or to tie the draw to scroll position precisely.
Why does my line draw on and then disappear?
You're missing forwards on the animation, so it resets to its first frame (invisible) when it ends. Add forwards to the shorthand, or set animation-fill-mode: forwards, to hold the finished line.
Can I do draw-on-scroll in Webflow without code?
Mostly. Webflow Interactions can animate stroke-dashoffset while an element scrolls into view, but the GUI doesn't always expose SVG sub-properties cleanly. When it won't, a five-line embed tying the offset to scroll position is the reliable fallback.
A line that draws itself is a small thing that makes a page feel built by someone who cared. If you'd rather hand the whole hero — animation, performance budget, and the part where it actually converts — to a senior bench that's wired this on real sites for years, that's what our Webflow development agency does. We'll keep the flourish and the 99/100.