A watering can tips forward, pours a stream of drops onto a sprout that perks up, then rights itself. Good for growth, onboarding and 'setting things up' moments.
Also known as: watering plant animation, garden loader css, growing plant loader.
<div class="ldr-watering-can" role="status" aria-label="Loading">
<svg viewBox="0 0 52 40" aria-hidden="true">
<ellipse class="ldr-watering-can-soil" cx="42" cy="38.6" rx="7" ry="1.6"/>
<circle class="ldr-watering-can-drop" cx="39.6" cy="20.5" r="1.6"/>
<circle class="ldr-watering-can-drop" cx="40.6" cy="20.5" r="1.4"/>
<circle class="ldr-watering-can-drop" cx="38.6" cy="20.5" r="1.4"/>
<g class="ldr-watering-can-sprout">
<path class="ldr-watering-can-stem" d="M42 38.5V30"/>
<path d="M42 33c-5 0-7-2.5-7-5.5 5 0 7 2.5 7 5.5zM42 31.5c4.5 0 6.5-2.2 6.5-5-4.5 0-6.5 2.2-6.5 5z"/>
</g>
<g class="ldr-watering-can-can">
<path class="ldr-watering-can-line" d="M9 9c0-9 14-9 14 0M25 23l13-13M36.5 8.5l3 3"/>
<rect x="5" y="8" width="21" height="19" rx="3.5"/>
</g>
</svg>
</div>.ldr-watering-can {
--s: var(--ldr-size, 48px);
--c: var(--ldr-color, #3b82f6);
width: calc(var(--s) * 1.3);
height: var(--s);
}
.ldr-watering-can svg {
display: block;
width: 100%;
height: 100%;
fill: var(--c);
}
.ldr-watering-can-line {
fill: none;
stroke: var(--c);
stroke-width: 3.4;
stroke-linecap: round;
}
.ldr-watering-can-can {
transform-origin: 29.8% 43.75%;
animation: ldr-watering-can-tip 2.8s infinite;
}
.ldr-watering-can-drop {
fill: color-mix(in srgb, var(--ldr-color, #3b82f6) 80%, transparent);
opacity: 0;
animation: ldr-watering-can-drop 2.8s infinite;
}
.ldr-watering-can-drop:nth-child(2) { animation-delay: 0.14s; }
.ldr-watering-can-drop:nth-child(3) { animation-delay: 0.28s; }
.ldr-watering-can-sprout {
transform-box: fill-box;
transform-origin: 50% 100%;
animation: ldr-watering-can-grow 2.8s infinite;
}
.ldr-watering-can-soil {
fill: color-mix(in srgb, var(--ldr-color, #3b82f6) 30%, transparent);
}
.ldr-watering-can-stem {
fill: none;
stroke: var(--c);
stroke-width: 2;
stroke-linecap: round;
}
@keyframes ldr-watering-can-tip {
0%, 16% { transform: rotate(0); animation-timing-function: cubic-bezier(0.4, 0, 0.3, 1.4); }
30%, 64% { transform: rotate(22deg); animation-timing-function: cubic-bezier(0.5, 0, 0.3, 1); }
80%, 100% { transform: rotate(0); }
}
@keyframes ldr-watering-can-drop {
0%, 30% { transform: translateY(0); opacity: 0; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.5); }
31% { transform: translateY(0); opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.5); }
43% { transform: translateY(16%); opacity: 1; }
45% { transform: translateY(16%); opacity: 0; }
46% { transform: translateY(0); opacity: 0; }
47% { transform: translateY(0); opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.5); }
59% { transform: translateY(16%); opacity: 1; }
61%, 100% { transform: translateY(16%); opacity: 0; }
}
@keyframes ldr-watering-can-grow {
0%, 40% { transform: scale(0.8); }
52% { transform: scale(1.1); }
60%, 84% { transform: scale(1); }
100% { transform: scale(0.8); }
}
@media (prefers-reduced-motion: reduce) {
.ldr-watering-can, .ldr-watering-can *, .ldr-watering-can::before, .ldr-watering-can::after, .ldr-watering-can *::before, .ldr-watering-can *::after {
animation-duration: 3s;
}
}--ldr-color on the element or a parent.
Currently previewing #3b82f6.--ldr-size. Every dimension in the snippet is
derived from it. Currently previewing 64px.animation shorthand.
Delays on the children are relative, so they keep their rhythm.role="status" and an
aria-label so screen readers announce the wait. The reduced-motion rule
at the end slows the animation for users who asked for less motion.