An accent card lifts off an isometric kanban board, glides from To do to Doing to Done and drops into place with a spring, then resets. Hairline SVG with CSS translate.
Also known as: kanban board animation, task board animation, hairline isometric.
<div class="hln-kanban-card-move" role="img" aria-label="A task card moving across a kanban board"> <svg viewBox="-110 -60 220 120" aria-hidden="true"><g transform="translate(0 2) scale(1.55)"><g><polygon points="-54,-10 20,27 20,25 -54,-12"/><polygon points="54,10 20,27 20,25 54,8"/><polygon points="-20,-29 54,8 20,25 -54,-12"/></g><line class="hln-kanban-card-move-in" x1="3" y1="-15.5" x2="-27" y2="-0.5"/><line class="hln-kanban-card-move-in" x1="27" y1="-3.5" x2="-3" y2="11.5"/><line class="hln-kanban-card-move-in" x1="-20" y1="-25" x2="-12" y2="-21"/><line class="hln-kanban-card-move-in" x1="4" y1="-13" x2="12" y2="-9"/><line class="hln-kanban-card-move-in" x1="28" y1="-1" x2="36" y2="3"/><g><g><polygon points="-32,-19 -14,-10 -14,-11.5 -32,-20.5"/><polygon points="-5,-14.5 -14,-10 -14,-11.5 -5,-16"/><polygon points="-23,-25 -5,-16 -14,-11.5 -32,-20.5"/></g><line class="hln-kanban-card-move-in" x1="-23" y1="-22" x2="-13" y2="-17"/><line class="hln-kanban-card-move-in" x1="-26" y1="-20.5" x2="-20" y2="-17.5"/></g><g><g><polygon points="-8,-7 10,2 10,0.5 -8,-8.5"/><polygon points="19,-2.5 10,2 10,0.5 19,-4"/><polygon points="1,-13 19,-4 10,0.5 -8,-8.5"/></g><line class="hln-kanban-card-move-in" x1="1" y1="-10" x2="11" y2="-5"/><line class="hln-kanban-card-move-in" x1="-2" y1="-8.5" x2="4" y2="-5.5"/></g><g><g><polygon points="16,5 34,14 34,12.5 16,3.5"/><polygon points="43,9.5 34,14 34,12.5 43,8"/><polygon points="25,-1 43,8 34,12.5 16,3.5"/></g><line class="hln-kanban-card-move-in" x1="25" y1="2" x2="35" y2="7"/><line class="hln-kanban-card-move-in" x1="22" y1="3.5" x2="28" y2="6.5"/></g><g class="hln-kanban-card-move-move"><g><polygon points="-43,-13.5 -25,-4.5 -25,-6 -43,-15"/><polygon points="-16,-9 -25,-4.5 -25,-6 -16,-10.5"/><polygon points="-34,-19.5 -16,-10.5 -25,-6 -43,-15"/></g></g></g></svg> </div>
.hln-kanban-card-move {
--c: var(--hln-color, #ff4f2e);
font-size: var(--hln-size, 16px);
position: relative;
display: grid;
place-items: center;
width: 22em;
height: 12em;
border-radius: 0.75em;
background: #f6f5f1;
overflow: hidden;
--u: 1px;
}
.hln-kanban-card-move svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-kanban-card-move svg * {
vector-effect: non-scaling-stroke;
}
.hln-kanban-card-move .hln-kanban-card-move-in {
stroke: #9a9ca3;
}
.hln-kanban-card-move .hln-kanban-card-move-move {
animation: hln-kanban-card-move-move 6.4s infinite;
}
.hln-kanban-card-move .hln-kanban-card-move-move > g > polygon:last-child {
fill: var(--c);
}
@keyframes hln-kanban-card-move-move {
0% { translate: 0 0; opacity: 0; }
4% { translate: 0 0; opacity: 1; }
10% { translate: 0 0; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
15% { translate: 0 calc(-5 * var(--u)); }
16% { translate: 0 calc(-5 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
30% { translate: calc(24 * var(--u)) calc(7 * var(--u)); }
31% { translate: calc(24 * var(--u)) calc(7 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
34.3% { translate: calc(24 * var(--u)) calc(12.4 * var(--u)); animation-timing-function: ease-in-out; }
35.8% { translate: calc(24 * var(--u)) calc(11.9 * var(--u)); animation-timing-function: ease-in-out; }
37% { translate: calc(24 * var(--u)) calc(12 * var(--u)); }
50% { translate: calc(24 * var(--u)) calc(12 * var(--u)); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
55% { translate: calc(24 * var(--u)) calc(7 * var(--u)); }
56% { translate: calc(24 * var(--u)) calc(7 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
70% { translate: calc(48 * var(--u)) calc(19 * var(--u)); }
71% { translate: calc(48 * var(--u)) calc(19 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
74.3% { translate: calc(48 * var(--u)) calc(24.4 * var(--u)); animation-timing-function: ease-in-out; }
75.8% { translate: calc(48 * var(--u)) calc(23.9 * var(--u)); animation-timing-function: ease-in-out; }
77% { translate: calc(48 * var(--u)) calc(24 * var(--u)); }
92% { translate: calc(48 * var(--u)) calc(24 * var(--u)); opacity: 1; }
98%, 100% { translate: calc(48 * var(--u)) calc(24 * var(--u)); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.hln-kanban-card-move * {
animation: none !important;
}
.hln-kanban-card-move .hln-kanban-card-move-move { translate: calc(24 * var(--u)) calc(12 * var(--u)); }
}
@media (prefers-reduced-motion: reduce) {
.hln-kanban-card-move, .hln-kanban-card-move *, .hln-kanban-card-move::before, .hln-kanban-card-move::after, .hln-kanban-card-move *::before, .hln-kanban-card-move *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hln-color on the element or a parent.
Currently previewing #3b82f6.--hln-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.