SVG✨ Premium

SVG Fill Animation

An SVG bottle whose gradient liquid rises to an adjustable level and drains again, on a loop — or rises once and stays at that level.

CSSClip-path

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. SVG has 30 effects, including 3 free. Explore the category →

3 usage examples

Rain-barrel level read in a connected vegetable garden app (Verdanelle) — SVG Fill Animation example 1

① Rain-barrel level read in a connected vegetable garden app (Verdanelle)

WhenOn the "Water and watering" page, the gardener taps "Read level": the tank on the card fills from the bottom up to 62%, next to the percentage and the litres left.
WhyThe rise gives the reading visible feedback, and the level reached reads at a glance, with the value written beside it for precision.
SettingsOutline and clip replaced by a rounded tank (same viewBox), --flb-level: .62, --flb-repeat: 1, --flb-speed: 1.5s, blues #1d6fe0 and #56c2f5, --flb-size: 104px, transparent background. The button hides then shows the root again, which replays the rise.
Small flask filling and draining inside a perfumer's "Blend it" button (Ambrevine) — SVG Fill Animation example 2

② Small flask filling and draining inside a perfumer's "Blend it" button (Ambrevine)

WhenAt the last step of composing a perfume, the customer clicks "Blend it": while it is being prepared, a 28 px flask fills and drains on a loop before "Blending…", then the button confirms the item was added to the basket.
WhyA filling flask speaks of perfume where a plain spinner would say nothing, and the back-and-forth signals a wait with no precise end.
Settings--flb-size: 28px, --flb-speed: .7s, gradient #d9467a to #f7b267, outline #2b2320, transparent background, --flb-min-h: 0. The root is only shown during the button's "busy" state, handled by the page.
Large bottle filling on and on across a distillery's "Our distillery" page (Genévrac) — SVG Fill Animation example 3

③ Large bottle filling on and on across a distillery's "Our distillery" page (Genévrac)

WhenOn a gin distillery's about page, a 270 px bottle slowly fills and empties to the right of the text, over a deep green background.
WhyThe bottle stands in for a product photo and brings movement to a text page, without ever going under the words.
Settings--flb-size: 270px, --flb-speed: 2.6s, gradient #2fb59f to #b9a7f5, cream outline at 75%, transparent background, root placed in position: absolute to the right of the text column.

How it works

The drawing fits a 100×120-unit SVG: the bottle outline (.flb-outline, 3-wide stroke), and a liquid rectangle (.flb-liquid) filled with a vertical indigo-to-magenta gradient, cut to the bottle's shape by a clipPath that reuses the same outline. The liquid is drawn after the outline, so it covers the inner half of it.

The flbFill animation moves the rectangle vertically: it starts 105 units lower (empty bottle) and rises to the level set by --flb-level (1 = full, 0.5 = half). It lasts --flb-speed (1.25 s, ease-in-out curve) and runs back and forth: the bottle fills then empties, 2.5 s per cycle. With --flb-repeat: 1, it fills once and stays at the chosen level. The gradient is attached to the liquid: halfway up, you mostly see its upper part.

The gradient and the clip need an id: with fixed ids, a second bottle on the page would pick up the first one's and lose its fill as soon as the first was hidden (tab, accordion). The short script therefore gives unique ids to every copy present at load. --flb-play: paused freezes the liquid wherever it is.

Accessibility

  • Decorative: the SVG carries aria-hidden="true". If it serves as a gauge, write the value as text next to it ("62%"): the bottle alone tells a screen reader nothing.
  • Reduced motion: with prefers-reduced-motion: reduce, the animation is removed and the liquid shows straight away at its level (full by default) — measured in all three engines, 0 running animations.
  • No interaction: nothing to click or reach with the keyboard; the effect is the same with a mouse, a finger or a keyboard.
  • Pace: one fill every 1.25 s, no flashing; for a long-running waiting indicator, a longer --flb-speed stays calmer.

Browser compatibility

SVG, CSS and 0.9 KB of JavaScript. Reduced motion needs Chrome 74, Firefox 63 and Safari 10.1. Measured in Chromium 151, Firefox 153 and WebKit 26.5: 0 errors, nothing added to window, two copies each with its own ids, and the 2nd keeps its fill when the 1st is hidden (2% coloured pixels in both cases).

Chrome 74+✓ Full (measured)
Firefox 63+✓ Full (measured)
Safari 10.1+✓ Full (measured in WebKit 26.5)
Edge 79+✓ Full (Chromium engine)
Safari iOS 10.3+✓ Full (WebKit engine, not tested on a device)
Chrome Android 74+✓ Full (Chromium engine)

Without JavaScript, a single bottle per page works normally; from two on, they share the same ids. Without CSS animations, the bottle shows filled to its level.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0602-root">
  <svg class="flb-svg" viewBox="0 0 100 120" aria-hidden="true">
    <defs>
      <linearGradient id="flb-grad" …>
        <stop class="flb-stop-1" …/>
        <stop class="flb-stop-2" …/>
      </linearGradient>
      <clipPath id="flb-clip"><path d="…"/></clipPath>
    </defs>
    <path class="flb-outline" d="…"/>
    <g class="flb-inside" clip-path="url(#flb-clip)">
      <rect class="flb-liquid" … fill="url(#flb-grad)"/>
    </g>
  </svg>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--flb-level 1 Level reached, from 0 (empty) to 1 (full): .62 for 62%.
--flb-repeat infinite 1: the bottle fills once and stays at its level; an even number: it ends empty.
--flb-speed 1.25s Length of one fill (a fill-and-drain cycle lasts twice as long).
--flb-play running paused freezes the liquid at its current height.
--flb-color-1 and --flb-color-2 #6366f1 and #d946ef Colours of the bottom and the top of the liquid.
--flb-line and --flb-size #6366f1 and 100px Outline colour and drawing width (the height follows, 1.2 times the width).
--flb-bg and --flb-min-h #0a0a0f and 300px Frame background and minimum height; transparent and 0 inside a button or a card.

FAQ

Yes: replace the d of the .flb-outline outline and of the clipPath path with the same outline. Keep the shape between heights 10 and 115 of the viewBox, otherwise the levels no longer land right.
The script only handles the copies present when it runs (it marks them with data-flb-ready). Run it again after inserting the new ones: it skips those already handled.
The gradient is attached to the liquid rectangle, which rises as a whole: its upper part shows first. For a single colour, give --flb-color-1 and --flb-color-2 the same value.