- var rings = 13;

.slinky
	- while (rings--) {
		.slinky__ring
	- }
View Compiled
// color
$hue: 223;
$sat: 90;
$light: 55;

// technical
$dur: 2s;
$rings: 13;
$curveSteps: 7; // controls the separation of rings on the curve
$ringH: 4em; // perceived ring diameter along the Z axis
$ringT: 0.25em;
$slinkyW: 8em; // diameter of all the rings
$slinkyCurveH: 10.75em; // height of the above space the curve should occupy
$hopGap: 1.5em; // space between slinky ends while moving

* {
	border: 0;
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}
:root {
	font-size: calc(16px + (24 - 16)*(100vw - 320px)/(1280 - 320));
}
body {
	background: #000;
	display: flex;
	font: 1em/1.5 sans-serif;
	height: 100vh;
}
.slinky {
	animation: camera $dur ease-in-out infinite;
	margin: auto;
	position: relative;
	width: $slinkyW;
	height: $rings * $ringT + $slinkyCurveH;
	&__ring {
		border-radius: 50%;
		box-shadow:
			0 0 0 $ringT hsl($hue,$sat,$light) inset,
			0 0 ($slinkyW/2 + $ringT * 2) hsla($hue,$sat,$light,0.3) inset,
			0 0 ($slinkyW/2 + $ringT) hsla($hue,$sat,$light,0.3);
		position: absolute;
		left: 0;
		width: inherit;
		height: $ringH;
		transform: translateY(0) rotateZ(0) rotateX(0) translateX(-$hopGap/2) {
			origin: 100% 50%;
		};
		@for $r from 0 to $rings {
			$child: $r + 1;
			&:nth-child(#{$child}) {
				animation: move#{$child} $dur linear infinite;
				bottom: $ringT * $r;
			}
		}
	}
}

// Animations
@keyframes camera {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-$slinkyW - $hopGap);
	}
}
$pctInc: 100% * 1/($rings + $curveSteps);
@for $r from 0 to $rings {
	@keyframes move#{$rings - $r} {
		$trans1: translateY(0) rotateZ(0) rotateX(0) translateX(-$hopGap/2);
		$trans2: translateY(-$ringT * $r) rotateZ(0) rotateX(0) translateX(-$hopGap/2);
		$trans3: translateY(-$ringT * $r) rotateZ(180deg) rotateX(180deg) translateX(-$hopGap/2);
		$trans4: translateY((-$ringT * $r) + ($ringT * ($rings - ($r + 1)))) rotateZ(180deg) rotateX(180deg) translateX(-$hopGap/2);
		// prevent negative starting percent
		@if $r > 0 {
			#{$pctInc * ($r - 1)} {
				transform: $trans1;
			}
		}
		#{$pctInc * $r} {
			transform: $trans2;
		}
		// stop the repeating of end percentages
		@if $r < $rings - 1	{
			#{$pctInc * ($r + $curveSteps)} {
				transform: $trans3;
			}
			#{$pctInc * ($r + $curveSteps + 1)}, 100% {
				transform: $trans4;
			}
		}
		@else {
			#{$pctInc * ($r + $curveSteps)}, 100% {
				transform: $trans3;
			}
		}
	}
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.