How to Avoid CSS3 Animation Minification Muddles

Craig Buckler
Share

Minification is one of the easier website optimization techniques. Even the simplest processor can shave a third off your CSS download size by concatenating separate file into one file and removing unnecessary characters. Typically, this involves deleting comments, white-space, and the last semi-colon in a rule set, e.g.

/* my page elements */
.element1, element2 {
  font-family: sans-serif;
  font-size: 1em;
  padding: 0px 0em 0vh 0rem;
  margin: 10px;
}

can be minified to:

.element1,element2{font-family:sans-serif;font-size:1em;padding:0px 0em 0vh 0rem;margin:10px}

Your browser doesn’t care that it’s less readable; as far as it’s concerned, the minified code is identical.

More advanced minifiers take the process further by removing unnecessary values and units. For example, the padding declaration from the previous code block can be reduced to:

padding:0 0 0 0;

or:

padding:0;

It’s this optimization that caused me several hours of frustration in a recent project. My local site worked fine but, on the the production build, CSS3 animation either failed to start or behaved erratically in some browsers. The cause? Minification…

Keyframe 0% != 0

The first issue was the declaration:

@keyframes blink {
  0%   { background-color: #fff; }
  50%  { background-color: #000; }
  100% { background-color: #fff; }
}

Some minifiers will translate the first keyframe in that example to:

0{background-color:#fff}

Unfortunately, zero is not a valid keyframe value. Some browsers will parse it as 0%, but others might start at the next valid keyframe or abandon animation altogether.

Timing 0s != 0

The animation shorthand property represents the following longhand animation properties:

<animation-name> || <time> || <timing-function> || <time> || <animation-iteration-count> || <animation-direction> || <animation-fill-mode>

For example:

animation: blink 2s ease 0s;

starts the ‘blink’ animation after zero seconds and repeats every two seconds using the ease timing function. However, the code might get minified to:

animation:blink 2s ease 0;

Some browsers will assume the final property is not a time but instead will read it as the animation-iteration-count value. Since that is zero, the animation will never start.

Mending the Minification Mess

You have two options if your minifier exhibits this behavior:

  1. Use a better, newer or simpler minification process. The YUI Compressor received a fix for CSS3 animation in February 2014.
  2. Change the way you write code, i.e. use the keyframes from keyword in place of 0% and omit timings of 0s or 0ms in shorthand animation declarations.

Neither option is ideal, but these are the challenges we web developers enjoy on a daily basis! Anyway, I hope this saves you a little of the pain I endured.

Have you found other CSS or JavaScript minification issues?