title: How to add physics to CSS animations?
body: <p>I'm just making a loading screen using CSS and I want it to have physically accurate behavior. I'm trying with the <code>animation-timing-function: cubic-bezier(1, 0, 1, 1)</code>, looks fine but not as real like I want, at first because I don't know how do <code>cubic-bezier</code> parameters really work, I found <a href="http://cubic-bezier.com/" rel="nofollow noreferrer">this</a> site and just played around with them until I got something nice.</p>
  <p>To sum up, how can I add physically accurate behavior to my animation?
  I am looking for a CSS-only solution, but JavaScript is fine too if it's impossible.</p>
  <p>Here you have an example:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body{
      background-color: #02a2bb;
  }
  
  .wrapper {
      padding: 50px;
      text-align: center;
  }
  .content {
      height: 125px;
      margin: 0 auto;
      position: relative;
      display: inline-block;
  }
  .ball {
      width: 25px;
      height: 25px;
      display: inline-block;
      border-radius: 50%;
      bottom: 0;
      position: relative;
      background-color: #fff;
      z-index: 1;
  }
  .ball-shadow {
      width: 20px;
      height: 6px;
      border-radius: 50%;
      position: absolute;
      bottom: 9px;
      left: 50%;
      -webkit-transform: translateX(-50%);
      -moz-transform: translateX(-50%);
      transform: translateX(-50%);
  }
  .animated {
      -webkit-animation-duration: 1s;
      -moz-animation-duration: 1s;
      -ms-animation-duration: 1s;
      -o-animation-duration: 1s;
      animation-duration: 1s;
      -webkit-animation-fill-mode: both;
      -moz-animation-fill-mode: both;
      -ms-animation-fill-mode: both;
      -o-animation-fill-mode: both;
      animation-fill-mode: both;
      -webkit-animation-iteration-count: infinite;
      -moz-animation-iteration-count: infinite;
      -ms-animation-iteration-count: infinite;
      -o-animation-iteration-count: infinite;
      animation-iteration-count: infinite;
  }
  .animated.jump, .animated.displace, .animated.diffuse-scale {
      -webkit-animation-duration: 3s;
      -moz-animation-duration: 3s;
      -ms-animation-duration: 3s;
      -o-animation-duration: 3s;
      animation-duration: 3s;
  }
  @-webkit-keyframes jump {
      0% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 0);
      }
      15% {
          opacity: 1;
          -webkit-transform: translate(0, 100px) scale(1.1, 0.9);
      }
      30% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 15px);
      }
      45% {
          opacity: 1;
          -webkit-transform: translate(0, 100px) scale(1.08, 0.92);
      }
      60% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 45px);
      }
      70% {
          opacity: 1;
          -webkit-transform: translate(0, 100px) scale(1.05, 0.95);
      }
      80% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 65px);
      }
      85% {
          opacity: 1;
          -webkit-transform: translate(0, 100px) scale(1.03, 0.97);
      }
      90% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 80px);
      }
      95% {
          opacity: 1;
          -webkit-transform: translate(0, 100px) scale(1.01, 0.99);
      }
      97% {
          opacity: 1;
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: translate(0, 95px);
      }
      100% {
          opacity: 0;
          -webkit-transform: translate(0, 100px);
      }
  }
  
  @keyframes jump {
      0% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 0);
          transform: translate(0, 0);
      }
      15% {
          opacity: 1;
          -moz-transform: translate(0, 100px) scale(1.1, 0.9);
          transform: translate(0, 100px) scale(1.1, 0.9);
      }
      30% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 15px);
          transform: translate(0, 15px);
      }
      45% {
          opacity: 1;
          -moz-transform: translate(0, 100px)scale(1.08, 0.92);
          transform: translate(0, 100px)scale(1.08, 0.92);
      }
      60% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 45px);
          transform: translate(0, 45px);
      }
      70% {
          opacity: 1;
          -moz-transform: translate(0, 100px)scale(1.05, 0.95);
          transform: translate(0, 100px)scale(1.05, 0.95);
      }
      80% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 65px);
          transform: translate(0, 65px);
      }
      85% {
          opacity: 1;
          -moz-transform: translate(0, 100px) scale(1.03, 0.97);
          transform: translate(0, 100px) scale(1.03, 0.97);
      }
      90% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 80px);
          transform: translate(0, 80px);
      }
      95% {
          opacity: 1;
          -moz-transform: translate(0, 100px) scale(1.01, 0.99);
          transform: translate(0, 100px) scale(1.01, 0.99);
      }
      97% {
          opacity: 1;
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: translate(0, 95px);
          transform: translate(0, 95px);
      }
      100% {
          opacity: 0;
          -moz-transform: translate(0, 100px);
          transform: translate(0, 100px);
      }
  }
  
  @-webkit-keyframes diffuse-scale {
      0% {
          box-shadow: 0 14px 8px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.5, 1) translateX(-50%);
      }
      15% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);
      }
      30% {
          box-shadow: 0 14px 7px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.4, 1) translateX(-50%);
      }
      45% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);    }
      60% {
          box-shadow: 0 14px 5px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.3, 1) translateX(-50%);    }
      70% {
          box-shadow: 0 14 2px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);
      }
      80% {
          box-shadow: 0 14px 4px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.2, 1) translateX(-50%);
      }
      85% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);
      }
      90% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.1, 1) translateX(-50%);
      }
      95% {
          box-shadow: 0 14px 3px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);
      }
      97% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -webkit-transform: scale(1.05, 1) translateX(-50%);
      }
      100% {
          -webkit-transform: scale(1, 1) translateX(-50%);
      }
  }
  @keyframes diffuse-scale {
      0% {
          box-shadow: 0 14px 8px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.5, 1) translateX(-50%);
          transform: scale(1.5, 1) translateX(-50%);
      }
      15% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
      30% {
          box-shadow: 0 14px 7px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.4, 1) translateX(-50%);
          transform: scale(1.4, 1) translateX(-50%);
      }
      45% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
      60% {
          box-shadow: 0 14px 5px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.3, 1) translateX(-50%);
          transform: scale(1.3, 1) translateX(-50%);
      }
      70% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
      80% {
          box-shadow: 0 14px 4px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.2, 1) translateX(-50%);
          transform: scale(1.2, 1) translateX(-50%);
      }
      85% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -webkit-transform: scale(1, 1) translateX(-50%);
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
      90% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.1, 1) translateX(-50%);
          transform: scale(1.1, 1) translateX(-50%);
      }
      95% {
          box-shadow: 0 14px 3px rgba(0, 0, 0, 0.5);
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
      97% {
          box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
          -moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
          animation-timing-function: cubic-bezier(1, 0, 1, 1);
          -moz-transform: scale(1.05, 1) translateX(-50%);
          transform: scale(1.05, 1) translateX(-50%);
      }
      100% {
          -moz-transform: scale(1, 1) translateX(-50%);
          transform: scale(1, 1) translateX(-50%);
      }
  }
  
  @-webkit-keyframes displace {
      from {
          -webkit-animation-timing-function: linear;
          -webkit-transform: translateX(0);
      }
      to {
          -webkit-transform: translateX(100px);
      }
  }
  @keyframes displace {
      from {
          -moz-animation-timing-function: linear;
          animation-timing-function: linear;
          -moz-transform: translateX(0);
          transform: translateX(0);
      }
      to {
          -moz-transform: translateX(100px);
          transform: translateX(100px);
      }
  }
  .jump {
      -webkit-animation-name: jump;
      -moz-animation-name: jump;
      -ms-animation-name: jump;
      -o-animation-name: jump;
      animation-name: jump;
  }
  .diffuse-scale {
      -webkit-animation-name: diffuse-scale;
      -moz-animation-name: diffuse-scale;
      -ms-animation-name: diffuse-scale;
      -o-animation-name: diffuse-scale;
      animation-name: diffuse-scale;
  }
  .displace {
      -webkit-animation-name: displace;
      -moz-animation-name: displace;
      -ms-animation-name: displace;
      -o-animation-name: displace;
      animation-name: displace;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="wrapper"&gt;
      &lt;div class="content animated infinite displace"&gt;
          &lt;span class="ball animated infinite jump"&gt;&lt;/span&gt;
          &lt;span class="ball-shadow animated infinite diffuse-scale"&gt;&lt;/span&gt;
      &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <h3>Suggestion</h3>
  <p>Something like a less or SCSS with constant physical variables that are defined, or values that you can add to the function  and sumule the physical behavior may even have already mixins that simulates certain behavior, I do not know something simple and only CSS.</p>