- const ARR = ['one', 'two', 'three', 'four', 'five', 'six']
mixin cube(className, id)
label.cube(class=className for=id)
div
div
block
div
div
div
div
for $input in ARR
input(type='checkbox' id=$input)
for $label in ARR
label.label-mask(for=$label)
.spinner.spinner--left
.spinner.spinner--right
.scene
.plane
+cube('plate')
.cake
for $slice in ARR
if ($slice !== 'six')
+cube('cake-slice', $slice)
if $slice === 'four'
span.css-label CSS is awesome
else
label.cube(class='cake-slice' for='six')
div
div
div
img.cake-bear(src='https://assets.codepen.io/605876/avatar.png')
div
div
div
for $shadow in ARR
span.cake-slice__shadow
.backdrop
View Compiled
*
box-sizing border-box
$starting-hue = 190
:root
--plate-depth 1
--marzipan hsl(50, 85%, 69%)
--marzipan-dark hsl(50, 85%, 50%)
--marzipan-light hsl(50, 85%, 78%)
--jammies hsl(7, 87%, 75%)
--jammies-dark hsl(7, 70%, 55%)
--cake hsl(43, 91%, 80%)
--cake-hover-y 2vmin
--cake-hover-z 3vmin
--cake-hover-rotate -10deg
--cake-active-y 3vmin
--cake-active-z 4vmin
--cake-active-rotate -10deg
--shadow-hover-translate -5%
--shadow-hover-opacity 0.15
--shadow-active-translate -8%
--shadow-active-opacity 0.05
--bg-hue $starting-hue
body
min-height 100vh
padding 0
margin 0
.scene
display flex
align-items center
justify-content center
perspective 800px
transform-style preserve-3d
margin 0
padding 0
height 100vh
width 100vw
// Used as a 3D set for the cake plate
.plane
height 30vmin
width 40vmin
transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg) rotate(0deg)
transform-style preserve-3d
[type='checkbox']
opacity 0
position fixed
left 100%
// Cube variables are scoped in here
.cube
position absolute
height calc(var(--height) * 1vmin)
width calc(var(--width) * 1vmin)
transform-style preserve-3d
// Dupe base
& > div:nth-of-type(1)
height 100%
width 100%
transform translate3d(0, 0, var(--offset, 0))
// Right face
& > div:nth-of-type(2)
position absolute
top 0
left calc(var(--width) * 1vmin)
height 100%
width calc(var(--depth) * 1vmin)
transform rotateY(-90deg) translate(var(--offset, 0), 0)
transform-origin 0 50%
// Left face
& > div:nth-of-type(3)
position absolute
top 0
left 0
height 100%
width calc(var(--depth) * 1vmin)
transform rotateY(-90deg) translate(var(--offset, 0), 0)
transform-origin 0 50%
// Back face
& > div:nth-of-type(4)
position absolute
top 0
left 0
height calc(var(--depth) * 1vmin)
width 100%
transform-origin 50% 0
transform rotateX(90deg) translate3d(0, var(--offset, 0), 0)
// Front face
& > div:nth-of-type(5)
position absolute
top 100%
left 0
width 100%
height calc(var(--depth) * 1vmin)
transform-origin 50% 0
transform rotateX(90deg) translate3d(0, var(--offset, 0), 0)
// The lid
& > div:nth-of-type(6)
height 100%
width 100%
position absolute
top 0
left 0
transform translateZ(calc(var(--depth) * 1vmin)) translate3d(0, 0, var(--offset, 0))
.plate
--height 25
--width 35
--depth 1
top 50%
left 50%
transform translate(-50%, -50%)
& > div:nth-of-type(2)
& > div:nth-of-type(3)
& > div:nth-of-type(4)
background hsl(0, 0%, 80%)
& > div:nth-of-type(5)
background hsl(0, 0%, 90%)
& > div:nth-of-type(6)
background hsl(0, 0%, 95%)
&:before
content ''
position absolute
left 100%
height 5vmin
width 1vmin
top 72%
transition transform 0.25s, opacity 0.25s
background hsl(0, 0%, 10%)
opacity 0
transform rotateY(-90deg) skewY(-20deg)
transform-origin 0 100%
&:after
content ''
position absolute
left 100%
height 20vmin
width 11.5vmin
transition transform 0.25s, opacity 0.25s
background hsl(0, 0%, 10%)
opacity 0
top 52%
transform-origin 0 50%
transform translate3d(0%, -50%, -0.2vmin) scaleX(0)
.cake
height 20vmin
width 30vmin
position absolute
top 50%
left 50%
transform-style preserve-3d
transform translate(-50%, -50%) translateZ(calc(var(--plate-depth) * 1vmin))
.cake-slice
--depth 15
--height 20
--width 5
--offset calc((var(--depth) / 2) * -1vmin)
position absolute
top 0
transition transform 0.25s
transform-origin 50% 100%
z-index 2
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin))
&:hover
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-hover-y), var(--cake-hover-z)) rotateX(var(--cake-hover-rotate))
& > div:nth-of-type(1)
background var(--marzipan-light)
& > div:nth-of-type(2)
background var(--marzipan-dark)
& > div:nth-of-type(3)
background var(--marzipan)
& > div:nth-of-type(4)
background var(--marzipan-light)
& > div:nth-of-type(5)
background var(--marzipan-light)
& > div:nth-of-type(6)
background var(--marzipan)
for $slice in 1..6
&:nth-of-type({$slice})
left 'calc((var(--width) * %s) * 1vmin)' % ($slice - 1)
&:hover ~ span:nth-of-type({$slice})
transform translateZ(0.00001vmin) translate(0, var(--shadow-hover-translate))
opacity var(--shadow-hover-opacity)
.cake-slice:nth-of-type(1)
.cake-slice:nth-of-type(2)
.cake-slice:nth-of-type(3)
.cake-slice:nth-of-type(4)
.cake-slice:nth-of-type(5)
& > div:nth-of-type(2)
background linear-gradient(var(--jammies), var(--jammies)) 10% 10% / 43% 43% no-repeat,
linear-gradient(var(--cake), var(--cake)) 90% 10% / 43% 43% no-repeat,
linear-gradient(var(--jammies), var(--jammies)) 90% 90% / 43% 43% no-repeat,
linear-gradient(var(--cake), var(--cake)) 10% 90% / 43% 43% no-repeat,
linear-gradient(var(--jammies-dark), var(--jammies-dark)) center center / 92% 92% no-repeat, var(--marzipan-light)
.cake-slice:nth-of-type(6)
& > div:nth-of-type(3)
background linear-gradient(var(--jammies), var(--jammies)) 10% 10% / 43% 43% no-repeat,
linear-gradient(var(--cake), var(--cake)) 90% 10% / 43% 43% no-repeat,
linear-gradient(var(--jammies), var(--jammies)) 90% 90% / 43% 43% no-repeat,
linear-gradient(var(--cake), var(--cake)) 10% 90% / 43% 43% no-repeat,
linear-gradient(var(--jammies-dark), var(--jammies-dark)) center center / 92% 92% no-repeat, var(--marzipan-light)
.css-label
display block
transform rotate(90deg) rotateY(180deg) translate(-25%, 15%)
position absolute
top 0
left 0
mix-blend-mode overlay
font-family sans-serif
font-weight bold
font-size 4vmin
.backdrop
height 200vh
width 200vw
position fixed
top 0
left 0
right 0
bottom 0
background 'hsl(%s, 20%, 40%)' % var(--bg-hue)
transform translateZ(-30vmin)
z-index -1
.cake-slice__shadow
--width 5
--alpha 1
display block
position absolute
height 100%
width calc(var(--width) * 1vmin)
background hsl(0, 0%, 10%)
transition transform 0.25s, opacity 0.25s
top 0
transform translateZ(0.00001vmin)
for $shadow in 1..6
&:nth-of-type({$shadow})
left 'calc((var(--width) * %s) * 1vmin)' % ($shadow - 1)
[type='checkbox']
for $checked in 1..6
&:nth-of-type({$checked}):checked
~ label:nth-of-type({$checked})
height 100vh
width 100vw
position fixed
z-index 11
opacity 0.3
transform translateZ(30vmin)
~ .scene .plane .cake .cake-slice:nth-of-type({$checked})
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate))
~ .scene .plane .cake .cake-slice__shadow:nth-of-type({$checked})
transform translateZ(0.00001vmin) translate(0, var(--shadow-active-translate))
opacity var(--shadow-active-opacity)
&:nth-of-type(1):checked ~ .backdrop
animation party-drop 1s infinite linear
&:nth-of-type(2):checked ~ .scene .plane .cake .cake-slice:nth-of-type(2)
animation cake-flip 1s infinite linear
&:nth-of-type(2):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(2)
animation shadow-flip 1s infinite linear
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(1)
animation cake-wave 1s 0.1s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(2)
animation cake-wave 1s 0.2s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(3)
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, 0, 0) rotateX(0)
animation cake-wave 1s 0.3s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(4)
animation cake-wave 1s 0.4s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(5)
animation cake-wave 1s 0.5s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice:nth-of-type(6)
animation cake-wave 1s 0.6s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(1)
animation shadow-wave 1s 0.1s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(2)
animation shadow-wave 1s 0.2s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(3)
opacity 1
animation shadow-wave 1s 0.3s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(4)
animation shadow-wave 1s 0.4s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(5)
animation shadow-wave 1s 0.5s infinite both
&:nth-of-type(3):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(6)
animation shadow-wave 1s 0.6s infinite both
&:nth-of-type(4):checked ~ .scene .plane .cake .cake-slice:nth-of-type(4)
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 20vmin) rotate(90deg)
// animation show-off 0.5s both
&:nth-of-type(4):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(4)
opacity 0
&:nth-of-type(5):checked ~ .scene .plane .cake .cake-slice:nth-of-type(5)
transform-origin 50% 50%
animation blast-off 2s
&:nth-of-type(5):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(5)
animation blast-shadow 2s
&:nth-of-type(6):checked ~ .scene .plane .cake .cake-slice:nth-of-type(6)
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, 0, 0) rotateX(0) translate3d(0, 0, 0) scale(1) rotate(0deg) translate3d(calc((var(--width)) * 2vmin), 0, calc(var(--width) * -1vmin)) rotateY(100deg)
&:nth-of-type(6):checked ~ .scene .plane .cake .cake-slice__shadow:nth-of-type(6)
opacity 0.8
transform translateZ(0.00001vmin) translate(100%, 0)
&:nth-of-type(6):checked ~ .scene .plane .plate:before
opacity 0.8
&:nth-of-type(6):checked ~ .scene .plane .plate:after
opacity 0.8
transform translate3d(0%, -50%, -0.2vmin) scaleX(1)
.spinner
height 100vh
width 15vw
position fixed
top 0
z-index 10
&:hover
~ .scene .plane
animation-name cake-spin
animation-duration 1s
animation-iteration-count infinite
animation-timing-function linear
&--left
left 0
&--right
right 0
&:hover ~ .scene .plane
animation-direction reverse
@keyframes party-drop
for $frame in (0..100)
{$frame * 1%}
background 'hsl(%s, 20%, 40%)' % (($frame * 3.6) + $starting-hue)
@keyframes cake-flip
0%
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 0) scale(1) rotate(0deg)
25%
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, -1vmin) scale(0.95) rotate(0deg)
50%
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 20vmin) scale(1.2)
75%
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 20vmin) scale(1.1) rotateX(-360deg)
100%
transform-origin 50% 50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 0) scale(1) rotate(-360deg)
@keyframes shadow-flip
25%
opacity 1
75%
opacity 0
@keyframes cake-spin
to
transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg) rotate(360deg)
@keyframes show-off
50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 15vmin) rotate(0deg)
100%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) translate3d(0, 0, 15vmin) rotate(90deg)
@keyframes blast-off
0%, 5%, 10%, 15%, 20%, 25%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(2deg) translate3d(0, 0, 0) scale(1)
2.5%, 7.5%, 12.5%, 17.5%, 22.5%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(-2deg) translate3d(0, 0, 0) scale(1)
80%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(0deg) translate3d(0, 0, 100vmin) scale(1)
80.1%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(0deg) translate3d(0, 0, 100vmin) scale(0)
80.2%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(0deg) translate3d(0, 0, 0) scale(0)
100%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, var(--cake-active-y), var(--cake-active-z)) rotateX(var(--cake-active-rotate)) rotateX(0deg) translate3d(0, 0, 0) scale(1)
@keyframes blast-shadow
80%
opacity 0
@keyframes cake-wave
0, 100%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, 0, 0) rotateX(0) translate3d(0, 0, 0)
50%
transform translate3d(0, 0, calc((var(--depth) / 2) * 1vmin)) translate3d(0, 0, 0) rotateX(0) translate3d(0, 0, 3vmin)
@keyframes shadow-wave
50%
transform translateZ(0.00001vmin) translate(0, var(--shadow-active-translate))
opacity var(--shadow-active-opacity)
.cake-bear
mix-blend-mode overlay
position absolute
width 100%
transform rotate(90deg) translate(15%, 0)
View Compiled
// 404
// Do something different with CSS
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.