div(class='loader')
- var n = 0;
while n < 8
div(class='box box' + n++)
div
div(class='ground')
div
small Weird Google Chrome Bug, you'll need to hover the body to make sure all is rendered - anyone knows a solution?
a(class='dribbble' href='https://dribbble.com/shots/7227469-3D-Boxes-Loader' target='_blank')
img(src='https://dribbble.com/assets/logo-small-2x-9fe74d2ad7b25fba0f50168523c15fda4c35534f9ea0b1011179275383035439.png')
View Compiled
:root {
--background: #121621;
}
.loader {
--duration: 3s;
--primary: rgba(39, 94, 254, 1);
--primary-light: #2f71ff;
--primary-rgba: rgba(39, 94, 254, 0);
width: 200px;
height: 320px;
position: relative;
transform-style: preserve-3d;
@media(max-width: 480px) {
zoom: .44;
}
&:before,
&:after {
--r: 20.5deg;
content: '';
width: 320px;
height: 140px;
position: absolute;
right: 32%;
bottom: -11px;
background: var(--background);
transform: translateZ(200px) rotate(var(--r));
animation: mask var(--duration) linear forwards infinite;
}
&:after {
--r: -20.5deg;
right: auto;
left: 32%;
}
.ground {
position: absolute;
left: -50px;
bottom: -120px;
transform-style: preserve-3d;
transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
div {
transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
width: 200px;
height: 200px;
background: var(--primary);
background: linear-gradient(45deg, var(--primary) 0%, var(--primary) 50%, var(--primary-light) 50%, var(--primary-light) 100%);
transform-style: preserve-3d;
animation: ground var(--duration) linear forwards infinite;
&:before,
&:after {
--rx: 90deg;
--ry: 0deg;
--x: 44px;
--y: 162px;
--z: -50px;
content: '';
width: 156px;
height: 300px;
opacity: 0;
background: linear-gradient(var(--primary), var(--primary-rgba));
position: absolute;
transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
animation: ground-shine var(--duration) linear forwards infinite;
}
&:after {
--rx: 90deg;
--ry: 90deg;
--x: 0;
--y: 177px;
--z: 150px;
}
}
}
.box {
--x: 0;
--y: 0;
position: absolute;
animation: var(--duration) linear forwards infinite;
transform: translate(var(--x), var(--y));
div {
background-color: var(--primary);
width: 48px;
height: 48px;
position: relative;
transform-style: preserve-3d;
animation: var(--duration) ease forwards infinite;
transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
&:before,
&:after {
--rx: 90deg;
--ry: 0deg;
--z: 24px;
--y: -24px;
--x: 0;
content: '';
position: absolute;
background-color: inherit;
width: inherit;
height: inherit;
transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
filter: brightness(var(--b, 1.2));
}
&:after {
--rx: 0deg;
--ry: 90deg;
--x: 24px;
--y: 0;
--b: 1.4;
}
}
&.box0 {
--x: -220px;
--y: -120px;
left: 58px;
top: 108px;
}
&.box1 {
--x: -260px;
--y: 120px;
left: 25px;
top: 120px;
}
&.box2 {
--x: 120px;
--y: -190px;
left: 58px;
top: 64px;
}
&.box3 {
--x: 280px;
--y: -40px;
left: 91px;
top: 120px;
}
&.box4 {
--x: 60px;
--y: 200px;
left: 58px;
top: 132px;
}
&.box5 {
--x: -220px;
--y: -120px;
left: 25px;
top: 76px;
}
&.box6 {
--x: -260px;
--y: 120px;
left: 91px;
top: 76px;
}
&.box7 {
--x: -240px;
--y: 200px;
left: 58px;
top: 87px;
}
}
$i: 0;
@while $i < 8 {
.box#{$i} {
animation-name: box-move#{$i};
div {
animation-name: box-scale#{$i};
}
}
$i: $i + 1;
}
}
$i: 0;
@while $i < 8 {
$delay: $i * 4;
@keyframes box-move#{$i} {
#{12 + $delay}% {
transform: translate(var(--x), var(--y));
}
#{25 + $delay}%,
52% {
transform: translate(0, 0);
}
80% {
transform: translate(0, -32px);
}
90%,
100% {
transform: translate(0, 188px);
}
}
@keyframes box-scale#{$i} {
#{6 + $delay}% {
transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
}
#{14 + $delay}%,
100% {
transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
}
}
$i: $i + 1;
}
@keyframes ground {
0%,
65% {
transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
}
75%,
90% {
transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(1);
}
100% {
transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
}
}
@keyframes ground-shine {
0%,
70% {
opacity: 0;
}
75%,
87% {
opacity: .2;
}
100% {
opacity: 0;
}
}
@keyframes mask {
0%,
65% {
opacity: 0;
}
66%,
100% {
opacity: 1;
}
}
body {
background: var(--background);
}
small {
display: block;
position: absolute;
bottom: 20px;
left: 50%;
font-family: Arial;
max-width: 320px;
font-size: 12px;
line-height: 19px;
z-index: 1;
color: #6C7486;
@media(min-width: 481px) {
transform: translateX(-50%);
text-align: center;
}
@media(max-width: 480px) {
left: 20px;
right: 112px;
font-size: 10px;
line-height: 17px;
transform: translateZ(400px);
}
}
html {
box-sizing: border-box;
font-smoothing: antialiased;
}
* {
box-sizing: inherit;
&:before,
&:after {
box-sizing: inherit;
}
}
// Center & dribbble
body {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.dribbble {
position: fixed;
display: block;
right: 24px;
bottom: 24px;
img {
display: block;
width: 76px;
}
}
}
View Compiled
// Weird Google Chrome Bug, you'll need to hover the body to make sure all is rendered - anyone knows a solution?
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.