How to Avoid CSS3 Animation Minification Muddles

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.

--ADVERTISEMENT--

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?