mixin cameras
  .camera.-x
    .camera.-y
      .camera.-z
        block

mixin bodyScales
  .scale.-top.-front
  .scale.-top.-back
  .scale.-bottom.-front
  .scale.-bottom.-back

+cameras()
  .under-sea
    .blowing-bubbles
      - for(i = 0; i < 40; i++)
        .bubble
    .swiming-fishes
      - for(i = 0; i < 10; i++)
        .swim
          .depth
            .rotate
              .fish-component
                .shadow
                .fish
                  .fish-body
                    .half.-left
                      +bodyScales()
                    .half.-right
                      +bodyScales()
                  .fish-tail
                    .scale.-top
                    .scale.-bottom
View Compiled
body {
  background: #1E5799;
  height: 100vh;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  perspective: 600px;
}

* {
  transform-style: preserve-3d;
}

div {
  position: absolute;
  transform-style: preserve-3d;
}

.camera {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  
  &.-x {
    transform: rotateX(-30deg);
  }
  
  &.-y {
    transform: rotateY(0deg);
    // animation: rotateY 10000ms linear infinite;
  }
  
  &.-z {
    // animation: rotateZ 30000ms linear infinite;
  }
}

$delay: 200ms;

.under-sea {
  transform: scale3d(0.4, 0.4, 0.4);
}

.blowing-bubbles {
  .bubble {
    @for $i from 1 through 40 {
      $size: random(20);
      &:nth-child(#{$i}) {
        left: random(80) - 40px;
        width: $size + 10px;
        height: $size + 10px;
        border-top: 1px solid #AFD2F7;
        border-radius: 100%;
        animation: bubbles random(4000) + 3000ms random(10000) * -1ms linear infinite;
      }
    }
  }
}

@keyframes bubbles {
  0% {
    transform: translateY(400px);
  }
  
  100% {
    transform: translateY(-1000px);
  }
}

.fish-body {
  .scale {
    position: static;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 0 50px 100px;
    animation: fishColor 1000ms linear infinite alternate;
    
    &.-top.-front {
      transform: scale(1, 1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg) translate(1.5px, 2.5px);
    }

    &.-top.-back {
      transform: scale(-1, 1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg) translate(1.5px, 2.5px);
    }

    &.-bottom.-front {
      transform: scale(1, -1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg) translate(1.5px, 2.5px);
    }

    &.-bottom.-back {
      transform: scale(-1, -1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg) translate(1.5px, 2.5px);
    }
  }
  
  > .half {
    display: flex;
    flex-wrap: wrap;
    width: 200px;
    height: 100px;
     
    &.-left {
      transform: translateZ(-1px);
      
      .scale.-top.-front {
        animation-delay: $delay * -1;
      }
      
      .scale.-top.-back {
        animation-delay: $delay * -2;
      }
      
      .scale.-bottom.-front {
        animation-delay: $delay * -3;
      }
      
      .scale.-bottom.-back {
        animation-delay: $delay * -4;
      }
    }

    &.-right {
      transform: scaleZ(-1) translateZ(-1px);
      
      .scale.-top.-front {
        animation-delay: $delay * -5;
      }
      
      .scale.-top.-back {
        animation-delay: $delay * -6;
      }
      
      .scale.-bottom.-front {
        animation-delay: $delay * -7;
      }
      
      .scale.-bottom.-back {
        animation-delay: $delay * -8;
      }
    }
  }
}

.fish-tail {
  top: 10px;
  left: -30px;
  transform-origin: 100% 50%;
  animation: fishMotion 500ms cubic-bezier(0.445, 0.050, 0.550, 0.950) infinite alternate;

  > .scale {
    position: static;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 0 40px 30px;
    animation: fishColor 1000ms linear infinite alternate;
    
    &.-top {
      transform: scale(-1, 1);
    }
    
    &.-bottom {
      transform: scale(-1, -1);
      animation-delay: $delay * -1;
    }
  }
}

.swiming-fishes {
  .rotate {
    width: 400px;
    transform-origin: 0 0;
    animation: rotateY 10000ms linear infinite;
  }
  
  .swim {
    @for $i from 1 through 10 {
      &:nth-child(#{$i}) {
        $depth: random(700);
        
        .rotate {
          width: random(600) + 200px;
          animation-delay: random(10000) * -1ms;
          animation-duration: random(6000) + 8000ms;
        }
        
        .depth {
          transform: translateY($depth * -1px);
        }
        
        .shadow {
          transform: translate(-50px, $depth + 200px) rotateX(90deg);
        }
        
        $fishDelay: random(2000);
        
        .fish {
          animation-delay: $fishDelay * -1 - 300ms;
        }

        .fish-tail {
          animation-delay: $fishDelay * -1ms;
        }
      }
    }
  }
}

.fish-component {
  top: -50px;
  right: 0;
  transform: rotateY(90deg) translateX(-100px);
  
  .fish {
    transform-origin: 100px 50px;
    animation: fishMotion 500ms -200ms cubic-bezier(0.445, 0.050, 0.550, 0.950) infinite alternate;
  }
  
  .shadow {
    width: 300px;
    height: 200px;
    background: radial-gradient(ellipse at center, rgba(#192C54, 0.2) 10%, rgba(#0E4791, 0) 50%);
  }
}

@keyframes rotateX {
  0% {
    transform: rotateX(0deg);
  }
  
  100% {
    transform: rotateX(360deg);
  }
}

@keyframes rotateY {
  0% {
    transform: rotateY(0deg);
  }
  
  100% {
    transform: rotateY(360deg);
  }
}

@keyframes rotateZ {
  0% {
    transform: rotateZ(0deg);
  }
  
  100% {
    transform: rotateZ(360deg);
  }
}

@keyframes fishColor {
  0% {
    border-color: transparent transparent #6C99C6 transparent;
  }
  
  100% {
    border-color: transparent transparent #1A5AB6 transparent;
  }
}

@keyframes fishMotion {
  0% {
    transform: rotateY(20deg);
  }
  
  100% {
    transform: rotateY(-20deg);
  }
}
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.