Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                mixin cube(className)
  .cube(class=className)
    - let s = 0
    while s < 6
      .cube__side
      - s++
input#toast(type='checkbox')
.rotater.rotater--top
.rotater.rotater--right
.rotater.rotater--bottom
.rotater.rotater--left
.scene
  .plane
    +cube('table')
    .toaster__shadow
    label.toaster(for='toast')
      .toast__wrapper
          .cube.toast
            .cube__side
            .cube__side
              .toast__face
                .eyes
                  .eye.eye--left
                  .eye.eye--right
                .mouth
            .cube__side
            .cube__side
            .cube__side
            .cube__side
      .toaster__toaster
        +cube('toaster__leg toaster__leg--tl')
        +cube('toaster__leg toaster__leg--tr')
        +cube('toaster__leg toaster__leg--br')
        +cube('toaster__leg toaster__leg--bl')
        .cube.toaster__body
          .cube__side
            img(src="https://assets.codepen.io/605876/bear-with-cap.svg")
            .toaster__face
              .eyes
                .eye.eye--left
                .eye.eye--right
              .mouth
          .cube__side
          .cube__side
            +cube('toaster__handle')
          .cube__side
          .cube__side
          .cube__side
      
label.cloak(for='toast')


              
            
!

CSS

              
                *
*:after
*:before
  box-sizing border-box

body
  min-height 100vh
  background hsl(195, 20%, 70%)
  overflow hidden
  margin 0
  padding 0

:root
  --toaster-width 18
  --toaster-height 10
  --toaster-depth 12
  --toast-depth 1
  --eye-size 1.75vmin
  --feature hsl(0, 0%, 5%)
  --shadow hsla(0, 0%, 25%, 1)
  --cloth-color-one hsla(320, 60%, 50%, 0.65)
  --speed 1
  --transition 0.25
  --handle hsl(0, 0%, 20%)
  --shade-one hsl(0, 0%, 85%)
  --shade-two hsl(0, 0%, 75%)
  --shade-three hsl(0, 0%, 65%)
  --shade-four hsl(0, 0%, 55%)
  --shade-five hsl(0, 0%, 45%)
  --shade-six hsl(0, 0%, 35%)
  --shine hsla(0, 0%, 100%, 0.5)


[type='checkbox']
  position absolute
  left 100%
  opacity 0
  height 0
  width 0

.rotater
  position fixed
  height 10vmin
  width 100vmax
  top 0
  left 0
  z-index 2

  &:hover
    & ~ .scene .plane
      animation spin-y 1s infinite linear

  &--bottom
    transform translate(0, calc(100vh - 10vmin))

    &:hover
      & ~ .scene .plane
        animation spin-y 1s infinite reverse linear

  &--left
    transform rotate(90deg)
    transform-origin 0 100%

    &:hover
      & ~ .scene .plane
        animation spin-x 1s infinite reverse linear

  &--right
    transform rotate(90deg) translate(0, calc(-100vw + 10vmin))
    transform-origin 0 100%

    &:hover
      & ~ .scene .plane
        animation spin-x 1s infinite linear


.scene
  perspective 800px
  transform-style preserve-3d
  height 100vh
  width 100vw
  display flex
  align-items center
  justify-content center

.plane
  height 20vmin
  width 40vmin
  transform-style preserve-3d
  transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg)
  // transform rotateX(-0deg) rotateY(-0deg) rotateX(90deg)

@keyframes spin-x
  to
    transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg) rotateZ(-360deg)
@keyframes spin-y
  to
    transform rotateX(-24deg) rotateY(-24deg) rotateX(90deg) rotateX(360deg)


.cube
  --width 15
  --height 10
  --depth 4
  height calc(var(--depth) * 1vmin)
  width calc(var(--width) * 1vmin)
  transform-style preserve-3d
  position absolute
  font-size 1rem
  animation spin 1s infinite linear
  transform translate3d(0, 0, 5vmin)

  & > div:nth-of-type(1)
    height calc(var(--height) * 1vmin)
    width 100%
    transform-origin 50% 50%
    transform rotateX(-90deg)
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin))

  & > div:nth-of-type(2)
    height calc(var(--height) * 1vmin)
    width 100%
    transform-origin 50% 50%
    transform translate(-50%, -50%) rotateX(-90deg) rotateY(180deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin))
    position absolute
    top 50%
    left 50%

  & > div:nth-of-type(3)
    height calc(var(--height) * 1vmin)
    width calc(var(--depth) * 1vmin)
    transform translate(-50%, -50%) rotateX(-90deg) rotateY(90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin))
    position absolute
    top 50%
    left 50%

  & > div:nth-of-type(4)
    height calc(var(--height) * 1vmin)
    width calc(var(--depth) * 1vmin)
    transform translate(-50%, -50%) rotateX(-90deg) rotateY(-90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin))
    position absolute
    top 50%
    left 50%

  & > div:nth-of-type(5)
    height calc(var(--depth) * 1vmin)
    width calc(var(--width) * 1vmin)
    transform translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * 1vmin))
    position absolute
    top 50%
    left 50%

  & > div:nth-of-type(6)
    height calc(var(--depth) * 1vmin)
    width calc(var(--width) * 1vmin)
    transform translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * -1vmin)) rotateX(180deg)
    position absolute
    top 50%
    left 50%

.table
  --height 2
  --width 40
  --depth 30
  position absolute
  top 50%
  left 50%
  transform translate(-50%, -50%)

  div
    background repeating-linear-gradient(90deg, var(--cloth-color-one) 2px, transparent 5px 9px, var(--cloth-color-one) 10px),
      repeating-linear-gradient(0deg, var(--cloth-color-one) 5px, transparent 6px 12px, var(--cloth-color-one) 15px), hsl(0, 0%, 90%)

img
  position absolute
  height 20%
  right 0.5vmin
  bottom 0.5vmin
  mix-blend-mode overlay
  filter grayscale(1)

:checked ~ .scene
  .toaster
    animation none

    .mouth
      background var(--feature)
      border 0

      &:after
        content ''

    &__handle
      transform translate3d(-50%, calc(var(--toaster-height) * 0.4vmin), calc(var(--height) * 0.5vmin))
      animation switch calc(var(--speed) * 1s) calc(var(--transition) * 1s) infinite ease-in-out

    .toast__wrapper
      transform translate3d(-50%, -50%, calc(var(--toaster-height) * 0.3vmin))
      animation jump calc(var(--speed) * 1s) calc(var(--transition) * 1s) infinite ease-in-out

    .toast
      animation flip calc(var(--speed) * 2s) calc(var(--transition) * 1s) infinite ease-in-out

    .toaster__body
      animation squish calc(var(--speed) * 1s) calc(var(--transition) * 1s) infinite ease-in-out

:checked ~ .cloak
  height 100vh
  width 100vw
  position absolute
  top 0
  left 0

.toaster
  height calc(var(--toaster-depth) * 1vmin)
  width calc(var(--toaster-width) * 1vmin)
  top 50%
  left 50%
  position absolute
  transform translate3d(-50%, -50%, 1vmin)
  transform-style preserve-3d

  &:hover
    animation rock calc(var(--speed) * 0.1s) infinite

    .mouth
      border 0
      &:before
        content ''

  &__shadow
    height calc(var(--toaster-depth) * 1vmin)
    width calc(var(--toaster-width) * 1vmin)
    top 50%
    left 50%
    position absolute
    transform translate3d(-50%, -50%, 1vmin)
    background var(--shadow)
    filter blur(10px)

  &__leg
    --width 1
    --depth 1
    --height 1
    position absolute
    transform translate3d(0, 0, 0.5vmin)

    --perimeter 5

    &--tr
      top calc(var(--perimeter) * 1%)
      left calc(var(--perimeter) * 1%)
    &--tl
      top calc(var(--perimeter) * 1%)
      right calc(var(--perimeter) * 1%)
    &--br
      bottom calc(var(--perimeter) * 1%)
      right calc(var(--perimeter) * 1%)
    &--bl
      bottom calc(var(--perimeter) * 1%)
      left calc(var(--perimeter) * 1%)

    div
      background var(--feature)

  &__body
    --depth var(--toaster-depth)
    --width var(--toaster-width)
    --height var(--toaster-height)
    position absolute
    top 50%
    left 50%
    transform translate3d(-50%, -50%, 6vmin)

    & > div:nth-of-type(1)
      background linear-gradient(120deg, transparent 10%, var(--shine) 10% 20%, transparent 20% 25%, var(--shine) 25% 30%, transparent 30%), var(--shade-one)
    & > div:nth-of-type(2)
      background var(--shade-four)
    & > div:nth-of-type(3)
      background var(--shade-three)
    & > div:nth-of-type(4)
      background var(--shade-three)
    & > div:nth-of-type(5)
      background var(--shade-two)
    & > div:nth-of-type(6)
      background var(--shade-two)

    & > div:nth-of-type(3)
      transform-style preserve-3d

      // handle slot
      &:after
        content ''
        position absolute
        width 8%
        height 50%
        background hsl(0, 0%, 40%)
        transform translate(-50%, 0)
        left 50%
        top 10%

    // bread slot
    & > div:nth-of-type(5):after
      content ''
      height 30%
      width 65%
      background hsl(0, 0%, 15%)
      top 50%
      left 50%
      position absolute
      transform translate(-50%, -50%)

  &__handle
    transform-style preserve-3d
    --height 1
    --width 3
    --depth 1
    position absolute
    top 10%
    left 50%
    transform translate3d(-50%, -50%, calc(var(--height) * 0.5vmin))
    background-color var(--handle)
    transition transform calc(var(--transition) * 1s) ease

    & > div
      background-color var(--handle)

  &__face
    height 25%
    width 50%
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)

  &__toaster
  &__body
  &__leg
    transform-style preserve-3d

  &__toaster
    height calc(var(--toaster-depth) * 1vmin)
    width calc(var(--toaster-width) * 1vmin)
    top 50%
    left 50%
    position absolute
    transform translate3d(-50%, -50%, 0)


.toast
  --depth var(--toast-depth)
  --height var(--toaster-height)
  --width var(--toaster-height)

  position absolute
  top 50%
  left 50%
  transform translate3d(-50%, -50%, calc(var(--toaster-height) * 0.5vmin))

  &__face
    height 30%
    width 80%
    top 50%
    left 50%
    position absolute
    transform translate(-50%, -50%)

  & > div
    background hsl(30, 40%, 80%)

    &:nth-of-type(1)
    &:nth-of-type(2)
      border 0.25vmin solid hsl(30, 80%, 40%)

    &:nth-of-type(3)
    &:nth-of-type(4)
    &:nth-of-type(5)
    &:nth-of-type(6)
      background hsl(30, 80%, 40%)

// Keyframes that need to match up on the double
// Bread jumps out and flips alternate ways
@keyframes jump
  0%, 100%
    transform translate3d(-50%, -50%, 3vmin)
  5%
    transform translate3d(-50%, -50%, 2vmin)
  50%
    transform translate3d(-50%, -50%, 20vmin)

@keyframes switch
  0%, 100%
    transform translate3d(-50%, calc(var(--toaster-height) * 0.4vmin), calc(var(--height) * 0.5vmin))
  5%
    transform translate3d(-50%, calc(var(--toaster-height) * 0.45vmin), calc(var(--height) * 0.5vmin))
  50%
    transform translate3d(-50%, -50%, calc(var(--height) * 0.5vmin))

@keyframes flip
  0%, 10%
    transform translate3d(-50%, -50%, calc(var(--toaster-height) * 0.5vmin)) rotateX(0deg) rotateZ(0deg)
  40%, 60%
    transform translate3d(-50%, -50%, calc(var(--toaster-height) * 0.5vmin)) rotateX(360deg) rotateZ(0deg)
  90%, 100%
    transform translate3d(-50%, -50%, calc(var(--toaster-height) * 0.5vmin)) rotateX(360deg) rotateZ(360deg)

// Toaster squish and then eject
@keyframes rock
  0, 100%
    transform translate3d(-50%, -50%, 1vmin) rotateY(1deg)
  50%
    transform translate3d(-50%, -50%, 1vmin) rotateY(-1deg)

@keyframes squish
  0%, 100%
    transform translate3d(-50%, -50%, 6vmin) scaleZ(1)
  5%
    transform translate3d(-50%, -50%, 6vmin) scaleZ(1.02)
  50%
    transform translate3d(-50%, -50%, 6vmin) scaleZ(0.98)

.toast__wrapper
  height calc(var(--toast-depth) * 1vmin)
  width calc(var(--toaster-height) * 1vmin)
  transform-style preserve-3d
  position absolute
  top 50%
  left 50%
  transform translate3d(-50%, -50%, 6vmin)
  transition transform calc(var(--transition) * 1s) ease
  // animation jump 1s infinite ease-in-out

.eye
  position absolute
  height var(--eye-size)
  width var(--eye-size)
  border-radius 50%
  background #000
  top 0
  animation blink 5s infinite

  &:after
    content ''
    height 25%
    width 25%
    position absolute
    top 10%
    left 10%
    border-radius 50%
    background hsl(0, 0%, 100%)

  &--left
    left 0

  &--right
    right 0

@keyframes blink
  0%, 49%, 51%, 100%
    transform scaleY(1)
  50%
    transform scaleY(0)

.mouth
  height 2.5vmin
  width 2.5vmin
  position absolute
  bottom 0
  left 50%
  transform translate(-50%, 0)
  -webkit-clip-path inset(50% 0 0 0)
  clip-path inset(50% 0 0 0)
  background #000
  border-radius 50%
  overflow hidden
  border 0.5vmin solid #000
  background transparent

  &:after
    // content ''
    height 60%
    width 60%
    position absolute
    top 75%
    left 50%
    background red
    border-radius 50%

  &:before
    height 50%
    width 50%
    border-radius 50%
    background #000
    top 50%
    position absolute
    left 50%
    transform translate(-50%, 0)
              
            
!

JS

              
                // JavaScript is toast in this demo 😅

// Click the toaster for bread flips!
// Hover page edges to rotate!
              
            
!
999px

Console