Professional in Drupal web development, theme designing, consultation and training

Classic animation in Facebook with CSS3 make it look fantastic

20 Aug 2014 - 08:38 pm

Have you ever notice that Facebook has a temporary nice shimmer animation before the real status fully appear? Did you know that Facebook do not use flash or GIF image for this animation? What's going on actually they only use CSS3 to make it.

CSS3 render much more faster, even faster compare to download and play any animated GIF. This design will to put all the processing and rendering part to user browser instead consuming time for downloading the images.

The idea is really easy. But in this post I just show the CSS part only. The full concept are using both Javascript and CSS. The temporary shimmer box will load as default. After a background query done and trigger by JavaScript, it will replace the whole box with actual status content.

CSS box design with gradient

First of all, we design a box with gradient shading. I put this box shading inside another box with 12px padding. The CSS code would be written like these:

<style type="text/css">
.box {
    background: #fff;
    border-color: #e5e6e9 #dfe0e4 #d0d1d5;
    border-radius: 3px;
    border-style: solid;
    border-width: 1px;
    padding: 12px;
.box-inside  {
    background: -webkit-linear-gradient(left center , #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100%) no-repeat scroll 0 0 / 800px 104px #f6f7f8;
    background: -moz-linear-gradient(left center , #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100%) no-repeat scroll 0 0 / 800px 104px #f6f7f8;
    background: linear-gradient(left center , #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100%) no-repeat scroll 0 0 / 800px 104px #f6f7f8;
    height: 104px;
    position: relative;

While below are the HTML code that will render the CSS code above. Take note for extra line which define for -webkit- and -moz- each of them specifically for Safari and Firefox browser compatibility.

<div class="box"><div class="box-inside"></div></div>

And the result would display like this:


Define CSS animation

Now we define the animation for .box-inside. We need a keyframe which define the path of animation to be guided. This keyframe action will make the gradient colour to move from current position at 0% to new the position at 100%.

If you look again at gradient position in first CSS definition, the background size were set at size of 800px x 104px which is overflow the .box-inside size. When keyframe took over, the gradient will flow from 0px to 468px from left to right to glide more nicer.

@-moz-keyframes placeHolderShimmer {
  0% {background-position:-468px 0}
  100% {background-position:468px 0}
@-webkit-keyframes placeHolderShimmer {
  0% {background-position:-468px 0}
  100% {background-position:468px 0}
@keyframes placeHolderShimmer {
  0% {background-position:-468px 0}
  100% {background-position:468px 0}

As usual, in CSS3 we need to specify additional attributes for Safari and Mozilla prefix. Lastly we create .animation class which include the keyframe name with additional attributes for animation to loop infinite.

.animation  {
  -webkit-animation: placeHolderShimmer 1s linear infinite forwards;
  -moz-animation: placeHolderShimmer 1s linear infinite forwards;
  animation: placeHolderShimmer 1s linear infinite forwards;

Blending all CSS with HTML

Next, we put additional class in .box-inside with .animation class to make it animate as you seen in Facebook site. We will get the result as below:


Masking with white overlay

Here is the complicated part. We must define at least 12 div items with unique attribute each of them. This to make a masking layer over the .box-inside with animation as the background.

Before that, we need to make sure that all div inside .box-inside applied default CSS attributes of positioning as absolute, start rendering from right and background of white via these definition:

.box-inside div {
  background: #fff;
  position: absolute;
  right: 0

For ease to recall, I will use class name using this pattern: mask01 until mask12. Let's try with first three div definition first.

.mask01 { height: 40px; width: 8px; right: auto; top: 0; left: 40px }
.mask02 { height: 8px; left: 48px; top: 0 }
.mask03 { height: 6px; left: 136px; top: 8px }

Later on, we put all this HTML code for rendering masking overlay layer with CSS class.

<div class="box">
  <div class="box-inside animation">
    <div class="mask01"></div>
    <div class="mask02"></div>
    <div class="mask03"></div>

So, how it would be look like to be? Well you need to observe it by yourself.


Continue to define the rest of div tag until finish. Or you can just copy the code I already wrote:

.mask04 { height: 12px; left: 48px;  top: 14px }
.mask05 { height: 6px;  left: 100px; top: 26px }
.mask06 { height: 10px; left: 48px;  top: 32px }
.mask07 { height: 20px; left: 0;     top: 40px }
.mask08 { height: 6px;  left: 410px; top: 60px }
.mask09 { height: 13px; left: 0;     top: 66px }
.mask10 { height: 6px;  left: 440px; top: 79px }
.mask11 { height: 13px; left: 0;     top: 85px }
.mask12 { height: 6px;  left: 178px; top: 98px }

What actually overlay do?

Overlaying div tags inside .box-inside will end up with the shape of "draft layout" look-a-like before actual status content fully load and pull from database. I put a temporary borders to all masking div tag to be campare with actual display without borders.


If I pull out the border, the result will totally look exactly you see in Facebook. Classic animation without any gif animation, just CSS3.


Have fun!

masking overlay