A hairline rack where one server blade slides out of its slot and settles with a spring. One @property length drives the moving front and the stretching top and side faces, so the blade stays exact.
Also known as: hairline animation, isometric server rack, server blade animation css.
<div class="hln-server-blade" role="img" aria-label="A server blade sliding out of a rack">
<svg viewBox="-110 -60 220 120" aria-hidden="true">
<g transform="translate(-3.1 11.8) scale(.88)">
<g><polygon points="-34,17 -6,31 -6,-27 -34,-41"/><polygon points="28,14 -6,31 -6,-27 28,-44"/><polygon points="0,-58 28,-44 -6,-27 -34,-41"/></g>
<line class="hln-server-blade-l" x1="-2" y1="-53" x2="18" y2="-43"/>
<line class="hln-server-blade-l" x1="-5" y1="-51.5" x2="15" y2="-41.5"/>
<line class="hln-server-blade-l" x1="-8" y1="-50" x2="12" y2="-40"/>
<line class="hln-server-blade-l" x1="-11" y1="-48.5" x2="9" y2="-38.5"/>
<g transform="matrix(1 -.5 0 -1 -6 31)"><rect x="3" y="4" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="6" x2="6" y2="9.5"/><line class="hln-server-blade-l" x1="7.6" y1="6" x2="7.6" y2="9.5"/><line class="hln-server-blade-l" x1="9.2" y1="6" x2="9.2" y2="9.5"/><line class="hln-server-blade-l" x1="10.8" y1="6" x2="10.8" y2="9.5"/><line class="hln-server-blade-l" x1="12.4" y1="6" x2="12.4" y2="9.5"/><line class="hln-server-blade-l" x1="14" y1="6" x2="14" y2="9.5"/><circle class="hln-server-blade-l" cx="22" cy="7.75" r="0.7"/><line class="hln-server-blade-l" x1="26" y1="6" x2="26" y2="9.5"/><rect x="3" y="13" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="15" x2="6" y2="18.5"/><line class="hln-server-blade-l" x1="7.6" y1="15" x2="7.6" y2="18.5"/><line class="hln-server-blade-l" x1="9.2" y1="15" x2="9.2" y2="18.5"/><line class="hln-server-blade-l" x1="10.8" y1="15" x2="10.8" y2="18.5"/><line class="hln-server-blade-l" x1="12.4" y1="15" x2="12.4" y2="18.5"/><line class="hln-server-blade-l" x1="14" y1="15" x2="14" y2="18.5"/><circle class="hln-server-blade-l" cx="22" cy="16.75" r="0.7"/><line class="hln-server-blade-l" x1="26" y1="15" x2="26" y2="18.5"/><rect x="3" y="22" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="24" x2="6" y2="27.5"/><line class="hln-server-blade-l" x1="7.6" y1="24" x2="7.6" y2="27.5"/><line class="hln-server-blade-l" x1="9.2" y1="24" x2="9.2" y2="27.5"/><line class="hln-server-blade-l" x1="10.8" y1="24" x2="10.8" y2="27.5"/><line class="hln-server-blade-l" x1="12.4" y1="24" x2="12.4" y2="27.5"/><line class="hln-server-blade-l" x1="14" y1="24" x2="14" y2="27.5"/><circle class="hln-server-blade-l" cx="22" cy="25.75" r="0.7"/><line class="hln-server-blade-l" x1="26" y1="24" x2="26" y2="27.5"/><rect class="hln-server-blade-l" x="3" y="31" width="28" height="7.5" rx="0.8"/><rect x="3" y="40" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="42" x2="6" y2="45.5"/><line class="hln-server-blade-l" x1="7.6" y1="42" x2="7.6" y2="45.5"/><line class="hln-server-blade-l" x1="9.2" y1="42" x2="9.2" y2="45.5"/><line class="hln-server-blade-l" x1="10.8" y1="42" x2="10.8" y2="45.5"/><line class="hln-server-blade-l" x1="12.4" y1="42" x2="12.4" y2="45.5"/><line class="hln-server-blade-l" x1="14" y1="42" x2="14" y2="45.5"/><circle class="hln-server-blade-l" cx="22" cy="43.75" r="0.7"/><line class="hln-server-blade-l" x1="26" y1="42" x2="26" y2="45.5"/><rect x="3" y="49" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="51" x2="6" y2="54.5"/><line class="hln-server-blade-l" x1="7.6" y1="51" x2="7.6" y2="54.5"/><line class="hln-server-blade-l" x1="9.2" y1="51" x2="9.2" y2="54.5"/><line class="hln-server-blade-l" x1="10.8" y1="51" x2="10.8" y2="54.5"/><line class="hln-server-blade-l" x1="12.4" y1="51" x2="12.4" y2="54.5"/><line class="hln-server-blade-l" x1="14" y1="51" x2="14" y2="54.5"/><circle class="hln-server-blade-l" cx="22" cy="52.75" r="0.7"/><line class="hln-server-blade-l" x1="26" y1="51" x2="26" y2="54.5"/></g>
<g transform="matrix(1 .5 -1 .5 25 -23)"><rect class="hln-server-blade-s" x="0" y="0" width="1" height="28"/></g>
<g transform="matrix(1 .5 0 -1 -3 -1.5)"><rect class="hln-server-blade-s" x="0" y="0" width="1" height="7.5"/></g>
<g class="hln-server-blade-f"><g transform="matrix(1 -.5 0 -1 -6 31)"><rect x="3" y="31" width="28" height="7.5" rx="0.8"/><line class="hln-server-blade-l" x1="6" y1="33" x2="6" y2="36.5"/><line class="hln-server-blade-l" x1="7.6" y1="33" x2="7.6" y2="36.5"/><line class="hln-server-blade-l" x1="9.2" y1="33" x2="9.2" y2="36.5"/><line class="hln-server-blade-l" x1="10.8" y1="33" x2="10.8" y2="36.5"/><line class="hln-server-blade-l" x1="12.4" y1="33" x2="12.4" y2="36.5"/><line class="hln-server-blade-l" x1="14" y1="33" x2="14" y2="36.5"/><circle class="hln-server-blade-af" cx="22" cy="34.75" r="0.8"/><line x1="26" y1="33" x2="26" y2="36.5"/></g></g>
</g>
</svg>
</div>.hln-server-blade {
--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;
}
.hln-server-blade svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-server-blade svg * {
vector-effect: non-scaling-stroke;
}
.hln-server-blade .hln-server-blade-l {
stroke: #9a9ca3;
}
.hln-server-blade .hln-server-blade-af {
fill: var(--c);
stroke: var(--c);
}
@property --hln-server-blade-e {
syntax: "<number>";
inherits: true;
initial-value: 16;
}
.hln-server-blade svg {
--hln-server-blade-e: 16;
animation: hln-server-blade-pull 5s infinite;
}
.hln-server-blade .hln-server-blade-s {
transform: scale(var(--hln-server-blade-e), 1);
}
.hln-server-blade .hln-server-blade-f {
transform: matrix(1, 0, 0, 1, var(--hln-server-blade-e), calc(var(--hln-server-blade-e) / 2));
}
@keyframes hln-server-blade-pull {
0% { --hln-server-blade-e: 0; }
12% { --hln-server-blade-e: 0; animation-timing-function: linear(0, 0.035, 0.125, 0.247, 0.384, 0.524, 0.655, 0.771, 0.87, 0.948, 1.008, 1.05, 1.077, 1.091, 1.095, 1.091, 1.083, 1.071, 1.058, 1.045, 1.032, 1.021, 1.012, 1.005, 0.999, 0.995, 0.993, 0.991, 0.991, 0.991, 0.992, 0.993, 1); }
34% { --hln-server-blade-e: 16; }
76% { --hln-server-blade-e: 16; animation-timing-function: cubic-bezier(.65,0,.35,1); }
90% { --hln-server-blade-e: 0; }
100% { --hln-server-blade-e: 0; }
}
@media (prefers-reduced-motion: reduce) {
.hln-server-blade * {
animation: none !important;
}
}
@media (prefers-reduced-motion: reduce) {
.hln-server-blade, .hln-server-blade *, .hln-server-blade::before, .hln-server-blade::after, .hln-server-blade *::before, .hln-server-blade *::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.