- 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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.