2

Material design guidelines provide an image loading pattern.

enter image description here

Since there is quite a lot of people following these guidelines, I was wondering if an implementation of it exists in css? It seems that using css filters with filters transtitions, it could be possible but I am not sure that it can be animated as described by the guidelines.

Note that I know there is a similar question but it is for native android development (Java).

To sum it up, can it be done and if so, has it be done?

Jose Alcérreca
  • 1,809
  • 17
  • 20
Billybobbonnet
  • 3,156
  • 4
  • 23
  • 49

1 Answers1

5

There is no gamma() for CSS filters yet, but you can try using brightness(). It is not the same thing, however, but perhaps close enough for a cigar?

In the example below I am using the cubic-bezier(0.7,0,0.6,1) timing function as an approximation of Google Material Design's "Heavy Move" easing function, but you can use any other cubic bezier curve definition to better approximate the timing function shown in Googles' MD chart. Here is the proof-of-concept example, with vendor prefixes added by JS.

Note: If the animation looks off, that's because the images not loaded before the animation runs. Re-run the code snippet if that's the case

html,
body {
  margin: 0;
  padding: 0;
}
.images {
  overflow: hidden;
}
.images img {
  /* Animation */
  animation: material-design__image 3s;
  animation-fill-mode: forward;

  /* Layout only */
  float: left;
  margin-right: 1rem;
  width: calc(50vw - 2rem);
}

/* Approximation of Material Design specifications */
@keyframes material-design__image {
  0% {
    opacity: 0;
    filter: saturate(20%) brightness(125%);
  }
  66.7% {
    opacity: 1;
  }
  83.3% {
    filter: saturate(87%) brightness(100%);
  }
  100% {
    filter: saturate(100%) brightness(100%);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="images">
  <img src="http://i.imgur.com/5nDXHEZ.jpg" alt="" title="" />
  <img src="http://i.imgur.com/hQNpUeA.jpg" alt="" title="" />
</div>

A little explanation of the keyframe definition:

  • Percentage stops are decided based on the Google MD chart you have provided. For a total duration of 3s, 66.7% corresponds to around the 2s timepoint, and 83.3% to the 2.5s timepoint.
  • Since filters cannot be stacked, we will have to manually compute the value of saturation (at 83.3% timepoint—if we do not declare the saturation, it will be reset to 100%). This value depends on the cubic-bezier curve you're using. For the curve that I am using in the code snippet, the value shoud be around 87% at 83.3%. This is a pure approximation, and inferred from here.
Terry
  • 63,248
  • 15
  • 96
  • 118
  • Very nice! I plan to use it in conjunction with an image lazy loading component, so the image should be preloaded. Hats off you sir! :-) – Billybobbonnet Apr 03 '16 at 11:38
  • 1
    @Billybobbonnet Thanks for the upvote and the accept! I have included some explanation of the keyframe animation, and further information on how I arrived at the saturation value at 83.3% timepoint :) – Terry Apr 03 '16 at 11:51