<form class="screen" novalidate>
<input id="start" type="checkbox" tabindex="-1">
<input id="end" type="checkbox" tabindex="-1">
<input id="last" type="checkbox" tabindex="-1">
<div class="sky">
<div></div>
<div></div>
</div>
<div class="base">
<input type="checkbox" tabindex="-1" required>
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<input type="checkbox" tabindex="-1">
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<input type="checkbox" tabindex="-1">
<div class="container horizontal">
<div class="block floating horizontal"></div>
<div class="block horizontal">
<label class="last" for="last" tabindex="-1"></label>
<div class="container vertical">
<div class="block floating vertical"></div>
<div class="block vertical">
<label class="end horizontal" for="end"></label>
<label class="end vertical" for="end"></label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="points"></div>
<label class="start" for="start" tabindex="-1">
PURE CSS<br>STACK
</label>
<button type="reset" tabindex="-1">
CLICK OR TAP<br>
TO RESTART
</button>
</form>
/* Layout */
body {
margin: 0;
background-color: black;
counter-reset: points;
}
.screen {
position: relative;
margin: 0 auto;
max-width: 100vw;
width: 75vh;
height: 100vh;
overflow: hidden;
}
/* Sky */
.sky {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
pointer-events: none;
}
.sky > div {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.sky > div::before {
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
display: block;
height: 1000vh;
}
.sky > div + div {
animation: opacity 30s linear infinite forwards paused;
}
/* All gradients except last are from https://uigradients.com/ */
.sky > div::before {
background: linear-gradient(
#f12711,
#f5af19 10%,
#91eae4 11%,
#86a8e7,
#7f7fd5 21%,
#f64f59 22%,
#c471ed,
#12c2e9 32%,
#f7797d 33%,
#fbd786,
#c6ffdd 43%,
#8a2387 44%,
#e94057,
#f27121 54%,
#3a1c71 55%,
#d76d77,
#fdbb2d 65%,
#22c1c3 66%,
#fdbb2d 76%,
#1a2a6c 77%,
#b21f1f,
#fdbb2d 87%
);
animation: sky 240s steps(8, end) infinite forwards paused;
}
.sky > div + div::before {
background: linear-gradient(
#ff0080,
#ff8c00,
#40e0d0 10%,
#1d2671 11%,
#c33764 21%,
#78ffd6 22%,
#a8ff78 32%,
#4b1248 33%,
#f0c27b 43%,
#2980b9 44%,
#6dd5fa,
#fff 54%,
#03001e 55%,
#7303c0,
#ec38bc,
#fdeff9 65%,
#56ccf2 66%,
#2f80ed 76%,
#0c0510 77%,
#160b3e,
#5f4282,
#cecc99 87%
);
animation: sky 240s steps(8, end) -15s infinite forwards paused;
}
/* Inputs and Last Label */
input,
.last {
z-index: 1;
position: absolute;
display: none;
width: 300vh;
height: 300vh;
opacity: 0;
cursor: pointer;
pointer-events: auto;
transform: translate(-150vh, -150vh);
touch-callout: none;
tap-highlight-color: transparent;
}
#last {
display: initial;
pointer-events: none;
}
input:checked,
#last:checked {
display: none !important;
}
/* Base */
.base {
position: relative;
left: calc(50% - 15vh);
top: 50vh;
width: 30vh;
height: 30vh;
background-color: red;
pointer-events: none;
transform: rotateX(45deg) rotateZ(45deg);
transform-style: preserve-3d;
transition: transform 0.5s ease-in-out;
}
/* Base Sides */
.base::before,
.base::after {
content: "";
z-index: -1;
position: absolute;
display: block;
}
.base::before {
right: 0;
width: 50vh;
height: 100%;
background: linear-gradient(to left, #d00, rgba(221, 0, 0, 0));
transform: rotateY(-90deg);
transform-origin: right;
}
.base::after {
bottom: 0;
width: 100%;
height: 50vh;
background: linear-gradient(to top, #e00, rgba(238, 0, 0, 0));
transform: rotateX(90deg);
transform-origin: bottom;
}
/* Containers */
.container {
position: absolute;
display: flex;
transform-style: preserve-3d;
}
.container.horizontal {
left: -45vh;
flex-direction: row;
width: calc(90vh + 100%);
height: 100%;
}
.container.vertical {
top: -45vh;
flex-direction: column;
width: 100%;
height: calc(90vh + 100%);
}
/* Spacers */
.container::before,
.container::after {
content: "";
}
.container.horizontal::before,
.container.horizontal::after {
max-width: calc(100% - 45vh);
min-width: 45vh;
height: 100%;
}
.container.vertical::before,
.container.vertical::after {
width: 100%;
max-height: calc(100% - 45vh);
min-height: 45vh;
}
/* Blocks */
.block {
position: relative;
visibility: hidden;
flex-grow: 1;
background-color: currentColor;
transform: translateZ(6vh);
transform-style: preserve-3d;
}
.block.horizontal {
height: 100%;
}
.block.vertical {
width: 100%;
}
.block.floating {
position: absolute;
display: none;
visibility: visible;
}
.block.floating.horizontal {
width: calc(100% - 90vh);
animation: left 2s linear alternate infinite both;
}
.block.floating.vertical {
height: calc(100% - 90vh);
animation: top 2s linear alternate infinite both;
}
/* Block Sides */
.block::before,
.block::after {
content: "";
z-index: -1;
position: absolute;
display: block;
background-color: currentColor;
}
.block::before {
right: 0;
width: 6vh;
height: 100%;
box-shadow: inset -6vh 0 rgba(0, 0, 0, 0.2);
transform: rotateY(-90deg);
transform-origin: right;
}
.block::after {
bottom: 0;
width: 100%;
height: 6vh;
box-shadow: inset 0 -6vh rgba(0, 0, 0, 0.1);
transform: rotateX(90deg);
transform-origin: bottom;
}
/* End Labels */
.end {
position: absolute;
left: -200vh;
top: -300vh;
visibility: visible;
max-width: 400vh;
max-height: 600vh;
pointer-events: auto;
cursor: pointer;
transform: rotateZ(-45deg) rotateX(-45deg) translateZ(100vh);
touch-callout: none;
tap-highlight-color: transparent;
}
.end.horizontal {
width: calc(400vh - 100000%);
height: 600vh;
}
.end.vertical {
width: 400vh;
height: calc(600vh - 100000%);
}
/* Points */
.points {
position: absolute;
left: 0;
right: 0;
top: 0;
display: none;
text-align: center;
color: white;
font-family: "Helvetica", "Roboto", "Segoe UI", "Arial", sans-serif;
font-size: 9vh;
font-weight: lighter;
pointer-events: none;
}
.points::before {
content: "YOU'VE REACHED THE TOP!";
display: block;
margin: 4vh auto;
font-size: 4vh;
opacity: 0;
transition: opacity 0.25s;
}
.points::after {
content: counter(points);
display: block;
}
/* Start Label */
.start {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
padding: 15vh 0;
text-align: center;
color: transparent;
text-shadow: 0 0 0 white;
font-family: "Helvetica", "Roboto", "Segoe UI", "Arial", sans-serif;
font-size: 9vh;
font-weight: lighter;
cursor: pointer;
transition: opacity 0.25s;
animation: start 0.75s linear;
user-select: none;
user-select: none;
user-select: none;
touch-callout: none;
tap-highlight-color: transparent;
}
.start::before {
content: "";
position: absolute;
left: calc(50% - 3vh);
top: 59.5vh;
display: block;
border-top: 5vh solid transparent;
border-bottom: 5vh solid transparent;
border-left: 8.5vh solid white;
}
.start::after {
content: "";
position: absolute;
left: calc(50% - 10vh);
top: 54.5vh;
display: block;
box-sizing: border-box;
border: solid 2vh white;
border-radius: 50%;
width: 20vh;
height: 20vh;
}
/* Restart Button */
button {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
border: none;
padding-top: 80vh;
width: 100%;
color: white;
background: transparent;
opacity: 0;
pointer-events: none;
font-family: "Helvetica", "Roboto", "Segoe UI", "Arial", sans-serif;
font-size: 4vh;
font-weight: lighter;
cursor: pointer;
transition: opacity 0.25s;
touch-callout: none;
tap-highlight-color: transparent;
}
/* Keyframes */
@keyframes opacity {
0% {
opacity: 1;
}
25% {
opacity: 1;
}
50% {
opacity: 0;
}
75% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes sky {
from {
transform: none;
}
to {
transform: translateY(-880vh);
}
}
@keyframes width {
from {
width: 0;
}
to {
width: 90vh;
}
}
@keyframes height {
from {
height: 0;
}
to {
height: 90vh;
}
}
@keyframes left {
from {
left: 0;
}
to {
left: 90vh;
}
}
@keyframes top {
from {
top: 0;
}
to {
top: 90vh;
}
}
@keyframes color {
0% {
color: #f00;
}
19% {
color: #ff0;
}
31% {
color: #0f0;
}
43% {
color: #0ff;
}
62% {
color: #00f;
}
81% {
color: #f0f;
}
100% {
color: #f00;
}
}
@keyframes start {
from {
text-shadow: 0 0 1vh white, 2vh -2vh 1vh white, 2vh 2vh 1vh white,
-2vh 2vh 1vh white, -2vh -2vh 1vh white;
opacity: 0;
}
to {
text-shadow: 0 0 0 white;
opacity: 1;
}
}
/* Sky: start changing */
#start:checked ~ .sky > div + div,
#start:checked ~ .sky > div::before {
animation-play-state: running;
}
/* Sky: stop changing */
#end:checked ~ .sky > div + div,
#end:checked ~ .sky > div::before,
#last:checked ~ .sky > div + div,
#last:checked ~ .sky > div::before {
animation-play-state: paused;
}
/* Base: start movement */
#start:checked ~ .base {
transform: translateY(200vh) rotateX(45deg) rotateZ(45deg);
transition-duration: 60s;
transition-timing-function: linear;
}
/* Base: stop movement */
#end:checked ~ .base,
#last:checked ~ .base {
transform: translateY(25vh) rotateX(45deg) rotateZ(45deg)
scale3d(0.3, 0.3, 0.3);
transition-duration: 1s;
transition-timing-function: ease-in-out;
}
/* Inputs and Last Label: display current */
#start:checked ~ .base > input,
input:checked + .container > .block > input,
input:checked + .container > .block > .last {
display: block;
}
/* Containers: start color rotation */
#start:checked ~ .base .container {
animation: color 60s linear alternate infinite both;
}
/* Containers: stop color rotation of current */
#start:checked ~ .base > .container,
input:checked + .container > .block > .container {
animation-play-state: paused !important;
}
/* Spacers: start sizing of current */
#start:checked ~ .base > .container.horizontal::before,
input:checked + .container > .block > .container.horizontal::before {
animation: width 2s linear infinite alternate both running;
}
#start:checked ~ .base > .container.horizontal::after,
input:checked + .container > .block > .container.horizontal::after {
animation: width 2s linear infinite alternate-reverse both running;
}
#start:checked ~ .base > .container.vertical::before,
input:checked + .container > .block > .container.vertical::before {
animation: height 2s linear infinite alternate both running;
}
#start:checked ~ .base > .container.vertical::after,
input:checked + .container > .block > .container.vertical::after {
animation: height 2s linear infinite alternate-reverse both running;
}
/* Spacers: stop sizing of current */
#end:active ~ .base .container::before,
#end:active ~ .base .container::after,
#end:checked ~ .base .container::before,
#end:checked ~ .base .container::after,
#last:active ~ .base .container::before,
#last:active ~ .base .container::after,
#last:checked ~ .base .container::before,
#last:checked ~ .base .container::after,
input:active + .container::before,
input:active + .container::after,
input:checked + .container::before,
input:checked + .container::after {
animation-play-state: paused !important;
}
/* Floating Blocks: display current */
#start:checked ~ .base > .container > .floating,
input:checked + .container > .block > .container > .floating {
display: block;
}
/* Floating Blocks: stop movement of current */
#end:active ~ .base .floating,
#last:active ~ .base .floating,
input:active + .container > .floating {
animation-play-state: paused;
}
/* Floating Blocks: stop movement of current then fadeout */
#end:checked ~ .base .floating,
#last:checked ~ .base .floating,
input:checked + .container > .floating {
visibility: hidden;
color: transparent;
transition: color 0.5s, background-color 0.5s, visibility 0s 0.5s;
animation-play-state: paused;
}
/* Increment Points */
#last:checked ~ .base .floating,
input:checked + .container > .floating {
counter-increment: points 1;
}
/* Floating Block Sides: stop sizing of current then fadeout */
#end:checked ~ .base .floating::before,
#end:checked ~ .base .floating::after,
#last:checked ~ .base .floating::before,
#last:checked ~ .base .floating::after,
input:checked + .container > .floating::before,
input:checked + .container > .floating::after {
visibility: hidden;
opacity: 0;
transition: opacity 0.5s, visibility 0s 0.5s;
animation-play-state: paused;
}
/* Blocks: show current */
input:checked + .container > .floating + .block,
#last:checked ~ .base .last + .container > .floating + .block {
visibility: visible;
}
/* Points: show only positive */
.screen:valid .points {
display: block;
}
/* Points: top reached */
#last:checked ~ .points::before {
opacity: 1;
}
/* Start Label: hide after started */
#start:checked ~ .start {
pointer-events: none;
opacity: 0;
animation: none;
}
/* Restart Button: show on end */
#end:checked ~ button,
#last:checked ~ button {
pointer-events: auto;
opacity: 1;
}
// ¯\_(ツ)_/¯
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.