CSS Flipping Text

CSS Flipping Text developed using HTML, CSS. Repeat delay in vanilla CSS with this flippin’ great boxes.

See the Pen CSS Flipping Text 🍳 by Jhey (@jh3y) on CodePen.

Created on March 10, 2020 Updated on March 10, 2020. A Pen by Jhey on CodePen.

- const word = 'Flip!'
.scene(style=`--hue: ${Math.random() * 360}; --saturation: ${Math.floor(Math.random() * 50 + 1) + 50}; --lightness: ${Math.floor(Math.random() * 25) + 50}`)
  .word
    - for (const [index, letter] of word.split('').entries())
      .letter__wrap(style=`--index: ${index}`)
        .letter(data-letter=letter)
          span.letter__panel(aria-hidden='true')= letter
          span.letter__panel(aria-hidden='true')= letter
          span.letter__panel= letter
          span.letter__panel

<div class="scene" style="--hue: 14.187122069046207; --saturation: 70; --lightness: 74">
  <div class="word">
    <div class="letter__wrap" style="--index: 0">
      <div class="letter" data-letter="F"><span class="letter__panel" aria-hidden="true">F</span><span class="letter__panel" aria-hidden="true">F</span><span class="letter__panel">F</span><span class="letter__panel"></span></div>
    </div>
    <div class="letter__wrap" style="--index: 1">
      <div class="letter" data-letter="l"><span class="letter__panel" aria-hidden="true">l</span><span class="letter__panel" aria-hidden="true">l</span><span class="letter__panel">l</span><span class="letter__panel"></span></div>
    </div>
    <div class="letter__wrap" style="--index: 2">
      <div class="letter" data-letter="i"><span class="letter__panel" aria-hidden="true">i</span><span class="letter__panel" aria-hidden="true">i</span><span class="letter__panel">i</span><span class="letter__panel"></span></div>
    </div>
    <div class="letter__wrap" style="--index: 3">
      <div class="letter" data-letter="p"><span class="letter__panel" aria-hidden="true">p</span><span class="letter__panel" aria-hidden="true">p</span><span class="letter__panel">p</span><span class="letter__panel"></span></div>
    </div>
    <div class="letter__wrap" style="--index: 4">
      <div class="letter" data-letter="!"><span class="letter__panel" aria-hidden="true">!</span><span class="letter__panel" aria-hidden="true">!</span><span class="letter__panel">!</span><span class="letter__panel"></span></div>
    </div>
  </div>
</div>
*
  box-sizing border-box
  transition all .15s ease 0s

:root
  --movement 0.85
  --stop 0.5
  --duration calc((var(--movement) * (1 / var(--stop))))
  --stagger 0.1125
  --perspective 500
  --size 50
  --ease cubic-bezier(1, -0.52, .26, .89)
  --bg hsl(0, 0%, 90%)
  --panel hsl(0, 0%, 100%)
  --color hsl(0, 0%, 5%)
  --hue 23
  --saturation 100
  --lightness 55

  @media(prefers-color-scheme dark)
    --bg hsl(0, 0%, 10%)
    --panel hsl(0, 0%, 0%)
    --color hsl(0, 0%, 95%)

body
  align-items center
  background var(--bg)
  display flex
  justify-content center
  min-height 100vh

.scene
  perspective calc(var(--perspective) * 1px)

.word
  display flex
  transform rotateX(-30deg) rotateY(45deg)
  transform-style preserve-3d

.letter__wrap
  animation flip calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) var(--ease) infinite
  transform-origin bottom center
  transform-style preserve-3d

  .letter
    animation rotate calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) ease infinite


.letter
  color var(--color)
  font-family -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif
  font-size 2rem
  font-weight bold
  height calc(var(--size) * 1px)
  margin-right calc(var(--size) * 0.2px)
  position relative
  text-transform uppercase
  transform-style preserve-3d
  width calc(var(--size) * 1px)

  &__panel
    align-items center
    background var(--panel)
    border '5px hsl(%s, %s, %s) solid' % (var(--hue) calc(var(--saturation) * 1%) calc(var(--lightness) * 1%))
    display flex
    height calc(var(--size) * 1px)
    justify-content center
    left 50%
    position absolute
    top 50%
    width calc(var(--size) * 1px)

    &:nth-of-type(1)
      transform translate3d(-50%, -50%, 0) rotateX(90deg) translate3d(0, 0, calc(var(--size) * 0.5px))
    &:nth-of-type(2)
      transform translate3d(-50%, -50%, calc(var(--size) * 0.5px)) rotateX(0deg)
    &:nth-of-type(3)
      transform translate3d(-50%, -50%, 0) rotateX(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px))
    &:nth-of-type(4)
      transform translate3d(-50%, -50%, 0) rotateY(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px))


@keyframes rotate
  0%, 22.5%
    transform rotateX(0deg)
  32.5%, 50%, 100%
    transform rotateX(90deg)

@keyframes flip
  0%, 50%, 100%
    transform scaleX(1) scaleY(1) translate(0, 0)
  15%
    transform scaleX(1.2) scaleY(0.8) translate(0, 0)
  25%
    transform scaleX(0.9) scaleY(1.1) translate(0, -100%)
* {
  box-sizing: border-box;
  -webkit-transition: all 0.15s ease 0s;
  transition: all 0.15s ease 0s;
}
:root {
  --movement: 0.85;
  --stop: 0.5;
  --duration: calc((var(--movement) * (1 / var(--stop))));
  --stagger: 0.1125;
  --perspective: 500;
  --size: 50;
  --ease: cubic-bezier(1, -0.52, 0.26, 0.89);
  --bg: #e6e6e6;
  --panel: #fff;
  --color: #0d0d0d;
  --hue: 23;
  --saturation: 100;
  --lightness: 55;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1a1a;
    --panel: #000;
    --color: #f2f2f2;
  }
}
body {
  -webkit-box-align: center;
          align-items: center;
  background: var(--bg);
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
          justify-content: center;
  min-height: 100vh;
}
.scene {
  -webkit-perspective: calc(var(--perspective) * 1px);
          perspective: calc(var(--perspective) * 1px);
}
.word {
  display: -webkit-box;
  display: flex;
  -webkit-transform: rotateX(-30deg) rotateY(45deg);
          transform: rotateX(-30deg) rotateY(45deg);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
}
.letter__wrap {
  -webkit-animation: flip calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) var(--ease) infinite;
          animation: flip calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) var(--ease) infinite;
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
}
.letter__wrap .letter {
  -webkit-animation: rotate calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) ease infinite;
          animation: rotate calc(var(--duration) * 1s) calc((var(--stagger, 0) * var(--index, 0)) * 1s) ease infinite;
}
.letter {
  color: var(--color);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  font-size: 2rem;
  font-weight: bold;
  height: calc(var(--size) * 1px);
  margin-right: calc(var(--size) * 0.2px);
  position: relative;
  text-transform: uppercase;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  width: calc(var(--size) * 1px);
}
.letter__panel {
  -webkit-box-align: center;
          align-items: center;
  background: var(--panel);
  border: 5px hsl(var(--hue), calc(var(--saturation) * 1%), calc(var(--lightness) * 1%)) solid;
  display: -webkit-box;
  display: flex;
  height: calc(var(--size) * 1px);
  -webkit-box-pack: center;
          justify-content: center;
  left: 50%;
  position: absolute;
  top: 50%;
  width: calc(var(--size) * 1px);
}
.letter__panel:nth-of-type(1) {
  -webkit-transform: translate3d(-50%, -50%, 0) rotateX(90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
          transform: translate3d(-50%, -50%, 0) rotateX(90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
}
.letter__panel:nth-of-type(2) {
  -webkit-transform: translate3d(-50%, -50%, calc(var(--size) * 0.5px)) rotateX(0deg);
          transform: translate3d(-50%, -50%, calc(var(--size) * 0.5px)) rotateX(0deg);
}
.letter__panel:nth-of-type(3) {
  -webkit-transform: translate3d(-50%, -50%, 0) rotateX(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
          transform: translate3d(-50%, -50%, 0) rotateX(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
}
.letter__panel:nth-of-type(4) {
  -webkit-transform: translate3d(-50%, -50%, 0) rotateY(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
          transform: translate3d(-50%, -50%, 0) rotateY(-90deg) translate3d(0, 0, calc(var(--size) * 0.5px));
}
@-webkit-keyframes rotate {
  0%, 22.5% {
    -webkit-transform: rotateX(0deg);
            transform: rotateX(0deg);
  }
  32.5%, 50%, 100% {
    -webkit-transform: rotateX(90deg);
            transform: rotateX(90deg);
  }
}
@keyframes rotate {
  0%, 22.5% {
    -webkit-transform: rotateX(0deg);
            transform: rotateX(0deg);
  }
  32.5%, 50%, 100% {
    -webkit-transform: rotateX(90deg);
            transform: rotateX(90deg);
  }
}
@-webkit-keyframes flip {
  0%, 50%, 100% {
    -webkit-transform: scaleX(1) scaleY(1) translate(0, 0);
            transform: scaleX(1) scaleY(1) translate(0, 0);
  }
  15% {
    -webkit-transform: scaleX(1.2) scaleY(0.8) translate(0, 0);
            transform: scaleX(1.2) scaleY(0.8) translate(0, 0);
  }
  25% {
    -webkit-transform: scaleX(0.9) scaleY(1.1) translate(0, -100%);
            transform: scaleX(0.9) scaleY(1.1) translate(0, -100%);
  }
}
@keyframes flip {
  0%, 50%, 100% {
    -webkit-transform: scaleX(1) scaleY(1) translate(0, 0);
            transform: scaleX(1) scaleY(1) translate(0, 0);
  }
  15% {
    -webkit-transform: scaleX(1.2) scaleY(0.8) translate(0, 0);
            transform: scaleX(1.2) scaleY(0.8) translate(0, 0);
  }
  25% {
    -webkit-transform: scaleX(0.9) scaleY(1.1) translate(0, -100%);
            transform: scaleX(0.9) scaleY(1.1) translate(0, -100%);
  }
}
W3TWEAKS

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *