- const DOLLS = 15
- const HUE_MAP = new Array(DOLLS).fill().map(() => Math.random() * 360)
form.dolls
- let d = 0
while d < DOLLS
- if (d !== (DOLLS - 1))
input(id=`doll--${d}`, type='checkbox')
label.doll(for=`doll--${d}`, style=`${d === 0 ? 'display: block;' : ''} --doll-index: ${d}; --hue: ${HUE_MAP[d]}; --next-hue: ${HUE_MAP[d + 1]}`)
span.doll__dummy-container
span.doll__dummy
span.face 🙂
span.doll__container
span.doll__half.doll__half--top
span.face 🙂
span.doll__half.doll__half--bottom
- d++
input(type="reset", id="reset")
label(for="reset") Reset
View Compiled
:root
--speed 0.25
--slide-distance 60
--base-width 100
--pop-height 60
--scale-step 0.05
--base-slide calc(var(--base-width) * 1)
@media(min-width 768px)
--base-width 300
body
align-items center
background #333
display flex
justify-content center
min-height 100vh
transform-style preserve-3d
::selection
background transparent
form
position relative
height 200px
width 100px
&:after
content ''
height 4px
position absolute
top 100%
background hsl(0, 0%, 85%)
left 50%
transform translate(-50%, 0)
width 200%
label
display none
[type='checkbox']
[type='reset']
display none
[for='reset']
color #fff
font-weight bold
cursor pointer
display block
position fixed
top 1rem
right 1rem
.doll
color #fff
cursor pointer
height 200px
position absolute
width 100px
&__half
background 'radial-gradient(hsl(0, 0%, 25%) 20%, transparent 20%) 5px 5px / 10px 10px,
radial-gradient(hsl(0, 0%, 100%) 20%, transparent 20%) 10px 10px / 10px 10px, hsl(%s, 80%, 75%)' % var(--hue)
position absolute
width 100%
height 50%
left 0
&--top
border-radius 50% 50% 0 0 / 40% 40% 0 0
top 0
&--bottom
border-radius 0 0 30% 30% / 0 0 45% 45%
bottom 0
&__container
&__dummy-container
height 100%
left 0
position absolute
top 0
width 100%
&__container
transform scale(calc(1 - ((var(--doll-index)) * var(--scale-step))))
transform-origin bottom
&__dummy
background 'radial-gradient(hsl(0, 0%, 25%) 20%, transparent 20%) 5px 5px / 10px 10px,
radial-gradient(hsl(0, 0%, 100%) 20%, transparent 20%) 10px 10px / 10px 10px, hsl(%s, 80%, 75%)' % var(--next-hue)
border-radius 50% 50% 30% 30% / 20% 20% 22.5% 22.5%
height 100%
left 0
position absolute
top 0
transform scale(calc(1 - ((var(--doll-index) + 1) * var(--scale-step))))
transform-origin bottom center
width 100%
input:checked + .doll + input + .doll
input:checked + .doll + .doll
display block
animation appear 0s calc(var(--speed) * 5s) both
input:checked + .doll
input:checked + .doll + input:checked + .doll
animation slideLeft calc(var(--speed) * 1s) forwards, slideOut calc(var(--speed) * 1s) calc(var(--speed) * 6s) forwards
pointer-events none
.doll__half--top
animation open calc(var(--speed) * 2s) calc(var(--speed) * 1s) forwards
.doll__dummy-container
animation move calc(var(--speed) * 2s) calc(var(--speed) * 3s) forwards, appear 0s calc(var(--speed) * 5s) reverse forwards
@keyframes slideLeft
to
transform translate(calc((var(--base-slide) * -1px) + var(--slide-distance) * -1%), 0)
@keyframes open
0%
transform translate(0, 0)
{100 / 3%}
transform translate(0, -100%)
{100/ 3 * 2%}
transform translate(-100%, -100%)
100%
transform translate(-100%, 100%)
@keyframes move
0%
transform translate(0, 0) translate(0,0)
{100 / 3%}
transform translate(0, calc(var(--pop-height) * -1%)) translate(0, 0)
{100/ 3 * 2%}
transform translate(0, calc(var(--pop-height) * -1%)) translate(calc((var(--base-slide) * 1px) + var(--slide-distance) * 1%), 0)
100%
transform translate(0, calc(var(--pop-height) * -1%)) translate(calc((var(--base-slide) * 1px) + var(--slide-distance) * 1%), calc(var(--pop-height) * 1%))
@keyframes slideOut
from
transform translate(calc((var(--base-slide) * -1px) + var(--slide-distance) * -1%), 0)
to
opacity 0
transform translate(calc((var(--base-slide) * -1px) + var(--slide-distance) * -2%), 0)
@keyframes appear
from
transform scale(0)
.face
position absolute
top 10px
left 50%
font-size 5rem
transform translate(-50%, 0)
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.