Search code examples
csssasscss-animationscompass-sass

Recreating Khan Academy's animated loading icon via CSS


Here is an online reference that recreate Khan Academy's animating loading icon.

DISCLAIMER: I am a complete newbie when it comes to SASS, COMPASS, or animating in CSS. Now that i got that out of the way, I have 2 questions:

1) This link works wonderfully with Chrome and Edge, but it doesn't work with IE11. Why does this not work with IE11?

2) I read thru the CSS section for this link reference. I cannot figure out how the 8 animated squared are generated. I understand the animation keyframes part. But I just don't see where the actual squares are declared. How/where is this generated?

* Updated * I found answer to question #1. I just modified the CSS to support IE11 (basically anything that says -webkit- I just removed.

For reference (and also because a codepen.io referenced post must have accompanied code):

@import "compass/css3";

$size: 30px;
$border: 2px;
$gray: #ddd;

$color: #3498D0;
$light: lighten($color, 10%);
$lighter: lighten($color, 20%);

body {
  padding: 30px 30px;
}

.square {
  position: relative;
  width: $size;
  height: $size;
  background: $gray;
  box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $gray

  ;
  -webkit-animation: loading 1s infinite ease-out;
}

@-webkit-keyframes loading {
  0% {
      background: $gray;
    box-shadow: 0px $size + $border $color,
              0px ($size + $border) * 2 $light,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $lighter;
  }
  12.5% { 
    background: $color;
    box-shadow: 0px $size + $border $light,
              0px ($size + $border) * 2 $lighter,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $gray;
  }
25% {
    background: $light;
    box-shadow: 0px $size + $border $lighter,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $color,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $gray;
}

37.5% {
    background: $lighter;
    box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $light,
              ($size + $border) * 2 0px $color,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $gray;
}

50% {
    background: $gray;
    box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $lighter,
              ($size + $border) * 2 0px $light,
              ($size + $border) * 2 $size + $border $color,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $gray;
}

62.5% {
    background: $gray;
    box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $lighter,
              ($size + $border) * 2 $size + $border $light,
              ($size + $border) * 2 ($size + $border) * 2 $color,
              $size + $border ($size + $border) * 2 $gray;
}

75% {
    background: $gray;
    box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $gray,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $lighter,
              ($size + $border) * 2 ($size + $border) * 2 $light,
              $size + $border ($size + $border) * 2 $color;
}

87.5% {
    background: $gray;
    box-shadow: 0px $size + $border $gray,
              0px ($size + $border) * 2 $color,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $lighter,
              $size + $border ($size + $border) * 2 $light;
}

100% {
    background: $gray;
    box-shadow: 0px $size + $border $color,
              0px ($size + $border) * 2 $light,
              $size + $border 0px $gray,
              ($size + $border) * 2 0px $gray,
              ($size + $border) * 2 $size + $border $gray,
              ($size + $border) * 2 ($size + $border) * 2 $gray,
              $size + $border ($size + $border) * 2 $lighter;
}

};

Solution

  • Actually you see eight square is box shadow, Just check CSS below

    body {
      padding: 10px 30px;
    }
    
    .square {
      position: relative;
      width: 30px;
      height: 30px;
      background: #ddd;
      box-shadow: 0px 32px #ddd, 0px 64px #ddd, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #ddd;
      -webkit-animation: loading 1s infinite ease-out;
    }
    
    @-webkit-keyframes loading {
      0% {
        background: #ddd;
        box-shadow: 0px 32px #3498D0, 0px 64px #5dadda, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #87c2e3;
      }
      12.5% {
        background: #3498D0;
        box-shadow: 0px 32px #5dadda, 0px 64px #87c2e3, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #ddd;
      }
      25% {
        background: #5dadda;
        box-shadow: 0px 32px #87c2e3, 0px 64px #ddd, 32px 0px #3498D0, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #ddd;
      }
      37.5% {
        background: #87c2e3;
        box-shadow: 0px 32px #ddd, 0px 64px #ddd, 32px 0px #5dadda, 64px 0px #3498D0, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #ddd;
      }
      50% {
        background: #ddd;
        box-shadow: 0px 32px #ddd, 0px 64px #ddd, 32px 0px #87c2e3, 64px 0px #5dadda, 64px 32px #3498D0, 64px 64px #ddd, 32px 64px #ddd;
      }
      62.5% {
        background: #ddd;
        box-shadow: 0px 32px #ddd, 0px 64px #ddd, 32px 0px #ddd, 64px 0px #87c2e3, 64px 32px #5dadda, 64px 64px #3498D0, 32px 64px #ddd;
      }
      75% {
        background: #ddd;
        box-shadow: 0px 32px #ddd, 0px 64px #ddd, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #87c2e3, 64px 64px #5dadda, 32px 64px #3498D0;
      }
      87.5% {
        background: #ddd;
        box-shadow: 0px 32px #ddd, 0px 64px #3498D0, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #87c2e3, 32px 64px #5dadda;
      }
      100% {
        background: #ddd;
        box-shadow: 0px 32px #3498D0, 0px 64px #5dadda, 32px 0px #ddd, 64px 0px #ddd, 64px 32px #ddd, 64px 64px #ddd, 32px 64px #87c2e3;
      }
    }