Mixing CSS3 Prefixed Properties with Keyframe Animations

on | 10 Comments

Mixing CSS3 Prefixed Properties with Keyframe AnimationsCurrently, there are still a number of CSS3 properties that will not work unless you include all the various vendor prefixes. And that number is growing now that IE10 has added support for a bunch of new properties and features.

Let’s look at a simple example of some CSS3 keyframe animation code that includes other prefixed CSS3 properties, and consider a problem that might arise when trying to future-proof the animation code.

As of this writing, the full code required to cover all current browser support, plus future support for the standard syntax, would look something like this:

.element {
	-webkit-animation: myanimation 2s ease 1 normal 2s;
	-moz-animation: myanimation 2s ease 1 normal 2s;
	animation: myanimation 2s ease 1 normal 2s;
}

@-webkit-keyframes myanimation {
	from {
		-webkit-transform: translateX(0);
	}

	to {
		-webkit-transform: translateX(100px);
	}
}

@-moz-keyframes myanimation {
	from {
		-moz-transform: translateX(0);
	}

	to {
		-moz-transform: translateX(100px);
	}
}

@keyframes myanimation {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(100px);
	}
}

Notice a couple of things here. First, the “from” and “to” keyframes for each supporting browser are using CSS3′s transform property. For each browser, the transform property has that browser’s prefix, which is inside the prefixed animation code. Second, we also have the standard “future-proof” code. So, whenever the browsers start to use the standard code, our code will be safe and will be using the latest implementation.

A Small Problem

The standard @keyframes section at the bottom of that chunk of code does not use any prefixes for the transform declarations. How do we know that the transform property will be “standard” when the animation code itself is “standard”?

So, if the browser starts reading the standard version of the code (and, I’m assuming, ignoring the previous vendor-based one…?), then would this mean that the animation would only work if the transform property was also standardized in that same browser?

What’s The Best Way to Write It?

I’m really not sure what the answer is. You could include all the transform-related prefixes in the standard code, and that would work just fine. Maybe something like this:

/* ... rest of the code up here ... */

@keyframes myanimation {
	from {
		-webkit-transform: translateX(0);
		-moz-transform: translateX(0);
		-ms-transform: translateX(0);
		transform: translateX(0);
	}

	to {
		-webkit-transform: translateX(100px);
		-moz-transform: translateX(100px);
		-ms-transform: translateX(100px);
		transform: translateX(100px);
	}
}

But it seems a bit awkward that way, doesn’t it? More than likely, this type of code will have to be revisited to ensure that whatever is inside the standard animation code is also currently working in the relevant browsers. And of course, I haven’t included any code for Opera here, so when they start supporting keyframe-based animations, then the code will be even bigger.

So, sorry to have no definite answers here, but I thought this would be worth mentioning so that anyone can propose the best solution for moving forward when mixing these types of CSS3 features.

10 Responses

  1. Scott:

    Hmm… I don’t know enough about CSS3 animation (haven’t got to that chapter in your book yet :D) but why *wouldn’t* a browser support “transform” when they supported “keyframes”? Or to put it another way, why support “keyframes” for animation if you don’t support the actual animation properties?

    Also, is it possible to condense the code to the following? Then surely the browser will run whichever properties it supports.

    
    @-webkit-keyframes myanimation,
    @-moz-keyframes myanimation,
    @-ms-keyframes myanimation,
    @keyframes myanimation {
        from {
            -webkit-transform: translateX(0);
            -moz-transform: translateX(0);
            -ms-transform: translateX(0);
            transform: translateX(0);
        }
        to {
            -webkit-transform: translateX(100px);
            -moz-transform: translateX(100px);
            -ms-transform: translateX(100px);
            transform: translateX(100px);
        }
    }
    
    • The transform property has nothing to do with CSS3 animation, that’s a separate property altogether. Inside the keyframes you can animate any properties that qualify as animatable (although I think that list in the previous link only applies to transitions; not sure if it extends to keyframes).

      So, if (for example) Mozilla starts supporting the standard syntax for keyframe animations, but still doesn’t offer support for the standard syntax for transform, then that’s where the conflict would arise.

      And yes, what you show there in your code example would definitely be ideal. But I don’t think that works. It probably should, but I don’t think it can be done that way.

    • Confirmed two things:

      The animatable properties list applies to transitions and keyframe animations, but a better list is provided on MDN

      And you definitely cannot comma-separate the at-rules that way. Browsers are programmed to ignore selectors they don’t recognize, so any vendor-prefixed at-rules would cause the entire declaration to be ignored. But those aren’t selectors, they’re at-rules, so they don’t work that way anyhow.

      • OK thanks for clarifying (I was just making guesses TBH). What is the transform property for if not for animation? If you’re just gonna move an element 100px to the right then you would just change the position or margin, right?

        P.S. your comment anchor links don’t seem to be working. The home page links to #comments on this page but it doesn’t jump down the page. The comments link at the top of the article links to #commentsdown which also doesn’t jump to the comments.

        • Thanks for pointing that out, Scott. I fixed it.

          I had done some tweaking to the comments.php file a week ago or so, and it seems I jacked it up. Unfortunately, WordPress has changed quite a bit of stuff since I wrote this theme, so it’s difficult (at least for me) to change things in the theme files when I’m running the latest version of WP.

          Thanks again.

  2. An interesting take on this. I think the current way to write is probably the best. The prefixes are there for browser vendors to allow experimentation of these features for feedback. One support is good enough, they can safely drop the prefix. If you ask me, animations will take the longest time for vendors to implement fully, so using prefixed properties *within* the keyframes will probably be useless.

    I think it’s safe to assume that most vendors will be able to jump straight from `-x-keyframes blah { from { -x-transform: ; } }` to the full non-prefixed version in one swift movement.

  3. Passerby:

    I whitelist your site from AdBlock, still I am getting unblock site message.

    • What browser/version/OS? I’ve tested in Chrome and Firefox, and whitelisting removes the message. It might happen once if there is a delay when loading the ads or something, but it generally shouldn’t happen.

  4. Igor:

    Note that there is no “@-ms-keyframes”, IE9 doesn’t support keyframes at all and IE10 uses “@keyframes” without vendor prefix.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.