A train with an accent locomotive crosses a hairline truss bridge, seen through the near truss, eases into the platform on the far bank, waits, then pulls away in a seamless loop.
Also known as: isometric train animation, train crossing bridge, hairline animation.
<div class="hln-train-bridge" role="img" aria-label="A train crosses a bridge and stops at a station"><svg viewBox="-41 -29.91 150 81.82" aria-hidden="true"><line x1="22" y1="5" x2="17" y2="7.5" class="hln-train-bridge-l"/><line x1="22" y1="15" x2="17" y2="17.5" class="hln-train-bridge-l"/><line x1="22" y1="25" x2="17" y2="27.5" class="hln-train-bridge-l"/><line x1="2" y1="21" x2="-3" y2="23.5" class="hln-train-bridge-l"/><line x1="42" y1="19" x2="37" y2="21.5" class="hln-train-bridge-l"/><line x1="4" y1="28" x2="-1" y2="30.5" class="hln-train-bridge-l"/><g><polygon points="-78,-21 -8,14 -8,4 -78,-31"/><polygon points="20,0 -8,14 -8,4 20,-10"/><polygon points="-50,-45 20,-10 -8,4 -78,-31"/></g><g><polygon points="32,34 112,74 112,64 32,24"/><polygon points="140,60 112,74 112,64 140,50"/><polygon points="60,10 140,50 112,64 32,24"/></g><g><polygon points="1.5,1.75 41.5,21.75 41.5,19.25 1.5,-0.75"/><polygon points="50.5,17.25 41.5,21.75 41.5,19.25 50.5,14.75"/><polygon points="10.5,-5.25 50.5,14.75 41.5,19.25 1.5,-0.75"/></g><polyline points="10.5,-5.25 16.5,-14.25 44.5,-0.25 50.5,14.75" fill="none" class="hln-train-bridge-l"/><line x1="16.5" y1="-2.25" x2="16.5" y2="-14.25" class="hln-train-bridge-l"/><line x1="23.5" y1="1.25" x2="23.5" y2="-10.75" class="hln-train-bridge-l"/><line x1="30.5" y1="4.75" x2="30.5" y2="-7.25" class="hln-train-bridge-l"/><line x1="37.5" y1="8.25" x2="37.5" y2="-3.75" class="hln-train-bridge-l"/><line x1="44.5" y1="11.75" x2="44.5" y2="-0.25" class="hln-train-bridge-l"/><line x1="16.5" y1="-2.25" x2="23.5" y2="-10.75" class="hln-train-bridge-l"/><line x1="23.5" y1="1.25" x2="30.5" y2="-7.25" class="hln-train-bridge-l"/><line x1="30.5" y1="4.75" x2="37.5" y2="-3.75" class="hln-train-bridge-l"/><line x1="37.5" y1="8.25" x2="44.5" y2="-0.25" class="hln-train-bridge-l"/><line x1="-62.5" y1="-38.75" x2="127.5" y2="56.25" class="hln-train-bridge-l"/><line x1="-65.5" y1="-37.25" x2="124.5" y2="57.75" class="hln-train-bridge-l"/><g class="hln-train-bridge-train"><g><polygon points="33,12.9 47,19.9 47,13.4 33,6.4"/><polygon points="53,16.9 47,19.9 47,13.4 53,10.4"/><polygon points="39,3.4 53,10.4 47,13.4 33,6.4"/></g><polygon points="34.5,10.75 37.2,12.1 37.2,10.1 34.5,8.75" class="hln-train-bridge-l"/><polygon points="38.7,12.85 41.4,14.2 41.4,12.2 38.7,10.85" class="hln-train-bridge-l"/><polygon points="42.9,14.95 45.6,16.3 45.6,14.3 42.9,12.95" class="hln-train-bridge-l"/><g><polygon points="49,20.9 63,27.9 63,21.4 49,14.4"/><polygon points="69,24.9 63,27.9 63,21.4 69,18.4"/><polygon points="55,11.4 69,18.4 63,21.4 49,14.4"/></g><polygon points="50.5,18.75 53.2,20.1 53.2,18.1 50.5,16.75" class="hln-train-bridge-l"/><polygon points="54.7,20.85 57.4,22.2 57.4,20.2 54.7,18.85" class="hln-train-bridge-l"/><polygon points="58.9,22.95 61.6,24.3 61.6,22.3 58.9,20.95" class="hln-train-bridge-l"/><g class="hln-train-bridge-a"><polygon points="65,28.9 79,35.9 79,29.4 65,22.4"/><polygon points="85,32.9 79,35.9 79,29.4 85,26.4"/><polygon points="71,19.4 85,26.4 79,29.4 65,22.4"/></g><g class="hln-train-bridge-a"><polygon points="74.5,26.65 79,28.9 79,26.4 74.5,24.15"/><polygon points="84,26.4 79,28.9 79,26.4 84,23.9"/><polygon points="79.5,21.65 84,23.9 79,26.4 74.5,24.15"/></g><polygon points="75,31 78,32.5 78,30.5 75,29"/><polygon points="84,31 80,33 80,30.5 84,28.5"/></g><polyline points="1.5,-0.75 7.5,-9.75 35.5,4.25 41.5,19.25" fill="none"/><line x1="7.5" y1="2.25" x2="7.5" y2="-9.75"/><line x1="14.5" y1="5.75" x2="14.5" y2="-6.25"/><line x1="21.5" y1="9.25" x2="21.5" y2="-2.75"/><line x1="28.5" y1="12.75" x2="28.5" y2="0.75"/><line x1="35.5" y1="16.25" x2="35.5" y2="4.25"/><line x1="7.5" y1="2.25" x2="14.5" y2="-6.25"/><line x1="14.5" y1="5.75" x2="21.5" y2="-2.75"/><line x1="21.5" y1="9.25" x2="28.5" y2="0.75"/><line x1="28.5" y1="12.75" x2="35.5" y2="4.25"/><line x1="16.5" y1="-14.25" x2="7.5" y2="-9.75"/><line x1="44.5" y1="-0.25" x2="35.5" y2="4.25"/><g><polygon points="39,24.5 75,42.5 75,41 39,23"/><polygon points="81,39.5 75,42.5 75,41 81,38"/><polygon points="45,20 81,38 75,41 39,23"/></g><line x1="47" y1="25" x2="47" y2="16.5"/><g><polygon points="45,16.5 47,17.5 47,16.3 45,15.3"/><polygon points="49,16.5 47,17.5 47,16.3 49,15.3"/><polygon points="47,14.3 49,15.3 47,16.3 45,15.3"/></g><line x1="65" y1="34" x2="65" y2="25.5"/><g><polygon points="63,25.5 65,26.5 65,25.3 63,24.3"/><polygon points="67,25.5 65,26.5 65,25.3 67,24.3"/><polygon points="65,23.3 67,24.3 65,25.3 63,24.3"/></g><polygon points="51,30.1 57,33.1 57,32.4 51,29.4" class="hln-train-bridge-l"/></svg></div>
.hln-train-bridge {
--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-train-bridge svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-train-bridge svg * {
vector-effect: non-scaling-stroke;
}
.hln-train-bridge-l {
stroke: #9a9ca3;
}
.hln-train-bridge-a {
fill: var(--c);
}
.hln-train-bridge-train {
animation: hln-train-bridge-train 8s linear infinite;
}
@keyframes hln-train-bridge-train {
0% { transform: translate(calc(var(--u) * -180), calc(var(--u) * -90)); animation-timing-function: cubic-bezier(.2, .55, .35, 1); }
42%, 62% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.55, 0, .9, .5); }
86% { transform: translate(calc(var(--u) * 130), calc(var(--u) * 65)); }
86.1%, 100% { transform: translate(calc(var(--u) * -180), calc(var(--u) * -90)); }
}
@media (prefers-reduced-motion: reduce) {
.hln-train-bridge * {
animation-play-state: paused !important;
animation-delay: calc(var(--delay, 0s) - 4s) !important;
}
}
@media (prefers-reduced-motion: reduce) {
.hln-train-bridge, .hln-train-bridge *, .hln-train-bridge::before, .hln-train-bridge::after, .hln-train-bridge *::before, .hln-train-bridge *::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.