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;
}