<div class="pl">
<div class="pl__sphere"></div>
<span class="pl__sphere-shadow"></span>
<div class="pl__sphere"></div>
<span class="pl__sphere-shadow"></span>
<div class="pl__sphere"></div>
<span class="pl__sphere-shadow"></span>
<div class="pl__sphere"></div>
<span class="pl__sphere-shadow"></span>
</div>
// Mixins
@mixin moveFilter($brightness,$blur)
filter: brightness($brightness) blur($blur)
filter: brightness($brightness) blur($blur)
@mixin sphere($color)
background: lighten($color,15%)
box-shadow: 0 -0.75em 0.5em $color inset, 0 0 0.5em fade-out(lighten($color,10%),0.3)
// Normal styles
$sphereDiam: 2em
$spaceBetween: 1em
$sphereCount: 4
$xGridOffset: 0.5em
$animDur: 2s
*
border: 0
box-sizing: border-box
margin: 0
padding: 0
\:root
font-size: calc(16px + (32 - 16) * (100vw - 320px) / (1280 - 320))
body
font: 1em/1.5 sans-serif
height: 100vh
.pl
background: linear-gradient(rgb(4,23,73) calc(50% + 1.5em),rgb(6,39,121) calc(50% + 2.5em) calc(50% + 10.5em), rgb(4,23,73))
position: relative
overflow: hidden
perspective: 800px
transform-style: preserve-3d
&, &:before
width: 100%
height: 100%
&:before, &__sphere, &__sphere-shadow
position: absolute
&:before, &__sphere-shadow
display: block
&:before
background: linear-gradient(rgb(6,39,121),rgba(6,39,121,0)), radial-gradient(100% 100% at 50% 50%,rgba(6,39,121,0) 37.5%,rgb(6,39,121) 50%), repeating-linear-gradient(0deg,rgba(8,55,170,0) 0 0.95em,rgb(8,55,170) 0.95em 1em), repeating-linear-gradient(90deg,rgba(8,55,170,0) 0 0.9em,rgb(8,55,170) 0.9em 1em) $xGridOffset 0
content: ""
top: 50%
left: 50%
transform: translate(-50%,-50%) rotateX(90deg) translateZ(-4em)
width: 34em
height: 34em
&__sphere
animation-name: moveSphere
@include sphere(hsl(223,90%,55%))
transform: translateZ(10em)
&, &-shadow
animation:
duration: $animDur
timing-function: ease-in-out
iteration-count: infinite
border-radius: 50%
top: calc(50% - #{$sphereDiam / 2})
left: calc(50% - #{$sphereDiam / 2})
width: $sphereDiam
height: $sphereDiam
z-index: 1
&-shadow
animation-name: moveSphereShadow
background-image: radial-gradient(100% 100% at center,rgba(0,0,0,0.2) 45%,rgba(0,0,0,0) 50%)
transform: translateY(4em) translateZ(10em) rotateX(90deg)
@for $s from 1 through $sphereCount
&:nth-of-type(#{$s}), &-shadow:nth-of-type(#{$s})
left: calc(50% - #{($sphereDiam + $spaceBetween) * (($sphereCount - ($s - 1)) - ($sphereCount / 2)) - ($spaceBetween / 2)})
@if $s > 1
animation-delay: ($animDur * 0.05) * ($s - 1)
// Animations
@keyframes moveSphere
from, to
@include moveFilter(100%,0)
transform: translateZ(10em)
25%, 75%
@include moveFilter(100%,0)
transform: translateZ(12em)
50%
@include moveFilter(80%,4px)
transform: translateZ(-10em)
@keyframes moveSphereShadow
from, to
transform: translateY(4em) translateZ(10em) rotateX(90deg)
25%, 75%
transform: translateY(4em) translateZ(12em) rotateX(90deg)
50%
transform: translateY(4em) translateZ(-10em) rotateX(90deg)
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.