mixin flaps(taped)
  .package__flap.package__flap--top
    if taped
      .package__tape.package__tape--top
  .package__flap.package__flap--bottom
    if taped
      .package__tape.package__tape--bottom

mixin side(taped = false)
  .package__side(class=`package__side--${attributes.class || 'side'}`)
    +flaps(taped)
    if block
      block

input#package(type="checkbox")
label.close(for="package") Close /
label.open(for="package") Open

.scene
  .gift
    .gift__gift
      svg(viewBox="0 0 362.6 388.5" role="img")
        path(d="M156.6,239l-88.3,64.8c-10.6,7.1-18.8,11.8-29.4,11.8c-21.2,0-38.9-18.8-38.9-40c0-17.7,14.1-30.6,27.1-36.5 l103.6-44.7L27.1,148.3C13,142.5,0,129.5,0,111.8C0,90.7,18.8,73,40,73c10.6,0,17.7,3.5,28.3,11.8l88.3,64.8L144.8,44.7 C141.3,20,157.8,0,181.3,0c23.5,0,40,18.8,36.5,43.6l-11.8,106l88.3-64.8c10.6-8.2,18.8-11.8,29.4-11.8c21.2,0,38.8,17.7,38.8,38.9 c0,18.8-12.9,30.6-27.1,36.5l-103.6,45.9L335.5,239c14.1,5.9,27.1,18.8,27.1,37.7c0,21.2-18.8,38.9-40,38.9 c-9.4,0-17.7-4.7-28.3-11.8L206,239l11.8,104.8c3.5,24.7-12.9,44.7-36.5,44.7c-23.5,0-40-18.8-36.5-43.6L156.6,239z" fill="hsl(25, 100%, 55%)")
    .gift__side.gift__side--right
    .gift__side.gift__side--front
    .gift__side.gift__side--left
      .gift__label
    .gift__side.gift__side--back
    .gift__lid.gift-lid
      .gift-lid__side.gift-lid__side--top
        .gift__ribbon
        .gift__ribbon
        .gift__ribbon
        .gift__ribbon
      .gift-lid__side.gift-lid__side--back
      .gift-lid__side.gift-lid__side--front
      .gift-lid__side.gift-lid__side--left
      .gift-lid__side.gift-lid__side--right
View Compiled
:root
  --height 20
  --width 20
  --depth 20
  --no-of-steps 12
  --primary-hue 260
  --secondary-hue 45
  --bg 'hsl(%s, 30%, 90%)' % var(--primary-hue)
  --primary 'hsl(%s, 80%, 50%)' % var(--primary-hue)
  --secondary 'hsl(%s, 100%, 50%)' % var(--secondary-hue)
  --ribbon-bg linear-gradient(90deg, var(--secondary) 0 10%, transparent 10% 25%, var(--secondary) 25% 75%, transparent 75% 90%, var(--secondary) 90%)
  --ribbon-bg-rotated linear-gradient(0deg, var(--secondary) 0 10%, transparent 10% 25%, var(--secondary) 25% 75%, transparent 75% 90%, var(--secondary) 90%)
  --ribbon-width calc(var(--width) * 0.2vmin)
  
*
*:after
*:before
  box-sizing border-box
  transform-style preserve-3d
  
body
  background var(--bg)
  min-height 100vh
  display grid
  place-items center
  perspective 100vmin
  overflow hidden
  
input
  position fixed
  top 0
  left 0
  width 1px
  height 1px
  padding 0
  margin -1px
  overflow hidden
  clip rect(0, 0, 0, 0)
  white-space nowrap
  border-width 0
  
.close
.open
  position fixed
  height 100vh
  width 100vw
  z-index 2
  transform scale(var(--scale, 1)) translate3d(0, 0, 50vmin)
  transition transform 0s var(--reveal-delay, calc(((var(--no-of-steps, 15) + 1) * var(--delay, 0.2)) * 1s))

#package:checked ~ .close
.open
  --scale 0
  --reveal-delay 0s

#package:checked ~ .open
  --scale 1
  --reveal-delay calc(((var(--no-of-steps, 15) + 1) * var(--delay, 0.2)) * 1s)

#package:checked ~ .scene
  --packaged 1
  
.scene
  transform rotateX(calc(var(--rotate-x, -24) * 1deg)) rotateY(calc(var(--rotate-y, -32) * 1deg)) rotateX(90deg) translate3d(0, 0, calc(var(--height, 20) * -0.5vmin))
  
  *
  *:after
  *:before
    --step-delay calc(var(--step, 1) - ((1 - var(--packaged, 0)) * (var(--step, 1) - ((var(--no-of-steps) + 1) - var(--step, 1)))))
    transition transform calc(var(--speed, 0.2) * 1s) calc((var(--step-delay) * var(--delay, 0.2)) * 1s) ease-in-out, opacity calc(var(--speed, 0.2) * 1s) calc((var(--step-delay) * var(--delay, 0.2)) * 1s) ease-in-out

    
.gift
  height calc(var(--depth) * 1vmin)
  width calc(var(--width) * 1vmin)
  background var(--primary)
  
  &__gift
    height calc(var(--height) * 1vmin)
    width calc(min(var(--width), var(--depth)) * 1vmin)
    position absolute
    bottom 50%
    transform-origin 50% 100%
    transform rotateX(-90deg) rotateY(45deg)
    
    svg
      height 50%
      position absolute
      left 50%
      top 50%
      opacity var(--packaged, 0)
      transform translate(-50%, -50%) translate(0, calc((1 - var(--packaged, 0)) * var(--height) * -1.25vmin))
      
  &__ribbon
    position absolute
    height 50%
    width var(--ribbon-width)
    background var(--ribbon-bg)
    left 50%
    bottom 50%
    transform-origin 50% 100%
    transform translate(-50%, 0) rotate(calc(var(--rotate, 0) * 1deg)) translate(0, 100%) scaleY(var(--packaged, 0))
    
    &:nth-of-type(1)
      --rotate 0
    &:nth-of-type(2)
      --rotate 90
    &:nth-of-type(3)
      --rotate 180
    &:nth-of-type(4)
      --rotate 270
      
  &__label
    position absolute
    height calc(var(--height) * 0.3vmin)
    width calc(var(--height) * 0.15vmin)
    background hsl(0, 0%, 98%)
    top 15%
    left 10%
    $clip = polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%)
    clip-path $clip
    -webkit-clip-path $clip
    transform-origin 50% 0
    transform scale(var(--packaged, 0))
    
    &:after
    &:before
      content ''
      background hsl(0, 0%, 25%)
      position absolute
      height calc(var(--h, 40) * 1%)
      width 20%
      top 50%
      left 50%
      transform-origin 50% 100%
      transform translate(-50%, -50%) translate(calc(var(--t, -1) * 60%), 0) scaleY(var(--packaged, 0))
      
    &:before
      --h 60
      --t 1
  
  &__lid
    height 100%
    width 100%
    transform scale(1.05) translate3d(0, 0, calc(((var(--height, 0) * (2 - var(--packaged, 0))) * 1vmin) + 4px))
  
  &__side
    background var(--primary)
    filter brightness(var(--b, 1))
    position absolute
    bottom 50%
    left 50%
    height calc(var(--height) * 1vmin)
    width calc(var(--width) * 1vmin)
    transform-origin 50% 100%
    transform translate(-50%, 0) rotate(calc(var(--rotate, 0) * 1deg)) translate(0, calc(var(--offset) * -0.5vmin)) rotateX(calc(var(--packaged, 0) * -90deg))
    
    &:after
      content ''
      position absolute
      height 100%
      transform-origin 50% 100%
      width var(--ribbon-width)
      background var(--ribbon-bg)
      top 50%
      left 50%
      transform translate(-50%, -50%) scaleY(var(--packaged, 0))
    
    &--left
    &--right
      --offset var(--width, 20)
      width calc(var(--depth) * 1vmin)
      
    &--front
    &--back
      --offset var(--depth, 20)
      width calc(var(--width) * 1vmin)
      
    &--right
      --b 0.8
      --rotate 0
    &--front
      --b 0.85
      --rotate 90
    &--left
      --b 0.9
      --rotate 180
    &--back
      --b 0.95
      --rotate 270
      
.gift-lid
  &__side
    opacity var(--packaged, 0)
    position absolute
    background var(--primary)
    height calc(var(--height) * 0.15vmin)
    width 100%
    filter brightness(var(--b, 1))
    
    &:after
      content ''
      height 100%
      background var(--ribbon-bg)
      width var(--ribbon-width)
      position absolute
      top 50%
      left 50%
      transform-origin 50% 100%
      transform translate(-50%, -50%) scaleY(var(--packaged, 0))

    &--top
      --b 1.1
      height 100%
      
      &:after
        display none

  
    &--back
      --b 0.8
      bottom 100%
      transform-origin 50% 100%
      transform rotateX(90deg)
      
      
    &--front
      --b 0.85
      top 100%
      transform-origin 50% 0%
      transform rotateX(-90deg)
      
    &--right
    &--left
      --b 0.8
      height 100%
      width calc(var(--height) * 0.15vmin)
      top 50%
      left 50%
      transform-origin 50% 0%
      transform translate(-50%, -50%) rotateY(calc(var(--coefficient, 1) * 90deg)) translate3d(0, 0, calc(var(--width) * 0.5vmin)) translate(calc(var(--coefficient, 1) * 50%), 0)
      
      &:after
        background var(--ribbon-bg-rotated)
        width 100%
        height var(--ribbon-width)
        transform-origin 100% 50%
        transform translate(-50%, -50%) scaleX(var(--packaged, 0))
    
    &--left
      --coefficient -1
    
// Steps
.gift__gift
  --step 1
.gift__side--right
  --step 2
.gift__side--front
  --step 3
.gift__side--left
  --step 4
.gift__side--back
  --step 5
.gift__lid
  --step 6
.gift__side:after
  --step 7
.gift-lid__side:after
  --step 8
.gift__ribbon
  --step 9
.gift__label
  --step 10
.gift__label:before
  --step 11
.gift__label:after
  --step 12
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.