Animated CSS/SVG Loading Icon

HTML
<div class="container"> <span class="loading-icon"> <strong>Loading</strong> <span class="inner-circle"> <span class="hourglass-inner"><b></b></span> <svg version="1.1" id="hourglass" viewBox="-49 141 512 512" xml:space="preserve"> <path class="hourglass" d="M237.4,413.4c-6.8-2.4-11.2-9.2-11.2-16.4c0-7.2,4.4-14,11.2-16.4c44-16.4,76-67.2,76.4-115.2H100.2 c0.4,48,32.4,98.4,76.4,115.2c6.8,2.4,11.2,9.2,11.2,16.4s-4.4,14-11.2,16.4c-44,16.4-76,67.2-76.4,115.2h213.6 C313.4,480.6,281.4,430.2,237.4,413.4z"/> <path class="hourglass-handle" d="M319.4,282.2H94.6c-8.4,0-15.6-6.8-15.6-15.6l0,0c0-8.4,6.8-15.6,15.6-15.6H319 c8.4,0,15.6,6.8,15.6,15.6l0,0C334.6,275.4,327.8,282.2,319.4,282.2z"/> <path class="hourglass-handle" d="M319.4,542.6H94.6c-8.4,0-15.6-6.8-15.6-15.6l0,0c0-8.4,6.8-15.6,15.6-15.6H319 c8.4,0,15.6,6.8,15.6,15.6l0,0C334.6,535.8,327.8,542.6,319.4,542.6z"/> </svg> </span> <svg class="circle-bg" viewBox="0 0 200 200"> <circle class="rotate" cx="100" cy="100" r="95"></circle> </svg> </span> </div>
SCSS
// Vars $border: 10px; $wh: 100px; $wh-inner: ($wh - $border); $anim-time: 2s; $sand-color: rgba(200, 255, 200, 1); $gradient-simple: linear-gradient(45deg, rgba(73, 155, 234, 1) 0%, rgba(32, 255, 229, 1) 100%); html, body { margin: 0; padding: 0; } .container { height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(45deg, rgba(73, 155, 234, 1) 0%, rgba(32, 255, 229, 1) 100%); } .loading-icon { height: $wh; width: $wh; border-radius: 100%; //box-shadow: 2px 2px 2px rgba(0,0,0,0.05); } .circle-bg { border-radius: 100%; background: $gradient-simple; } .inner-circle { height: $wh-inner; width: $wh-inner; transform: rotate(90deg); //background: #fff; position: absolute; top: 50%; left: 50%; margin-top: -($wh-inner / 2); margin-left: -($wh-inner / 2); border-radius: 100%; //box-shadow: inset 2px 2px 2px rgba(0,0,0,0.05); animation: hourglass-rotate ($anim-time + 2) ease-in-out infinite alternate; } // PERCENT CIRCLE ANIMATION @keyframes hourglass-rotate { 0% { transform: rotate(0); } 35% { transform: rotate(0); } 65% { transform: rotate(180deg); } 100% { transform: rotate(180deg); } } circle.rotate { transform: rotate(-90deg); transform-origin: 50% 50%; stroke-width: ($border * 2); stroke: rgba(255, 255, 255, 0.25); fill: transparent; stroke-dasharray: 600; stroke-dashoffset: 600; animation: anim-circle-border $anim-time ease-in-out infinite alternate; } // PERCENT CIRCLE ANIMATION @keyframes anim-circle-border { 0% { stroke-dashoffset: 600; } 50% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -600; } } .hourglass-inner { position: absolute; width: 100%; height: 100%; // BEFORE & AFTER &::before, &::after { content: ""; position: absolute; width: 26px; height: 9px; left: 32px; background: $sand-color; border-radius: 3px 3px 350px 350px; top: 28px; } &::before { animation: sand-down-before ($anim-time * 2 + 4) ease-in-out infinite; animation-delay: 4s; } &::after { border-radius: 350px 350px 0px 0px; top: 53px; animation: sand-down-before ($anim-time * 2 + 4) ease-in-out infinite; } b { position: absolute; background: $sand-color; width: 3px; height: 20px; top: 35px; left: 49%; &::before, &::after { content: ""; width: 0; height: 0; left: -9px; border: 10px solid transparent; position: absolute; z-index: 1; } // TOP ARROW &::before { top: 0; border-top-color: $sand-color; } // BOTTOM ARROW &::after { bottom: 0; border-bottom-color: $sand-color; } } } // SAND DOWN :: BEFORE ANIMATION @keyframes sand-down-before { 0% { background-color: $sand-color; } 35% { background-color: $sand-color; } 50% { background-color: transparent; } 70% { background-color: transparent; } 100% { background-color: $sand-color; } } // SVG .hourglass { fill: rgba(0, 0, 0, 0.05); } // SVG .hourglass-handle { fill: rgba(73, 155, 234, 1); } // SR only .loading-icon strong { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; }
JAVASCRIPT
Expand for more options Login