I’ve fallen into the habit of creating CSS animations in my free time, inspired by things I come across during the day. To create the animations as I imagine them using as few elements as possible, I’ve found some tricks to make CSS do things you might not know it could do. I’d like to share them with you.
#1) Jump to another state mid-animation
CSS animation makes it easy to transition properties to a new value over time. They also have the ability to jump properties to a new value virtually instantly. The trick is to use two keyframes with a very small difference, around .001%
works well.
@keyframes toggleOpacity {
50% { opacity: 1; } /* Turn off */
50.001% { opacity: 0.4; }
/* Keep off state for a short period */
52.999% { opacity: 0.4; } /* Turn back on */
53% { opacity: 1; }
}
The following is an extreme example of this, toggling opacity and a text-shadow to mimic a flickering billboard light.
See the Pen No Vacancy 404 CSS Only by Zach Saucier (@Zeaklous) on CodePen.
#2) Negative animation delays
A positive animation delay is where the animation waits a certain amount of time to begin. A negative animation delay starts the animation immediately, as if that amount of time has already gone by. In other words, start the animation at a state further into the animation cycle. This allows animations to be reused across several elements, given all that needs changing is the timing.
Here is an example of that where each circle begins immediately at a different state in the animation cycle:
See the Pen Circle Snake by Zach Saucier (@Zeaklous) on CodePen
#3) Proportional animations
I try to make everything that I put into production be as responsive as possible, including my animations. Responsiveness for CSS animations is not possible for all animations I have created, but sometimes it is, using percentages and other relative units.
In many of my animations, I use elements like circles and squares which need the a proportional width and height. You might think I need to use fixed width & height values to keep them that way, but that’s not the case! I am able to create them using a percentage width, zero height, and percentage padding. The padding-bottom is the trick to keep it proportional to the width, like this:
.container {
position: relative;
display: block;
width: 100%;
height: 0;
padding-bottom: 100%;
}
You can see this in practice on the following demo by changing the size of the window it is in. The demo also makes use of negative animation delays.
See the Pen Responsive CSS bars by Zach Saucier (@Zeaklous) on CodePen.
#4) Changing transform-origin mid-animation
While working on one of my animations, I was surprised to find out that not only can transformation-origin
be changed mid-animation, it is also animatable! In the example below, this allows us to create one animation using rotations on different axes instead of using four separate animations.
See the Pen Change transformation-origin mid animation by Zach Saucier (@Zeaklous) on CodePen
The downside to this trick is that you can’t use animation-mode: forwards;
for only a part of an animation. This means that we have to re-position the element to an equivalent of its state before applying the change in transformation-origin
. In the above example, this is done by using translates to mimic the rotation’s effects. However, this technique can get tedious on more complex examples, as seen here.
#5) Negative transform-origins
You are able to set a negative transform-origin
, which is useful for things like creating circular movement paths. Instead of specifying specific translate and rotation values using one element to create circular animations as Lea Verou describes, we can do it much more simply by using negative transform-origin
values in addition to a second element or pseudo-element (one element if we want the element to rotate as well as move in a circular path). By using varying values of a negative transform origin, we can reuse the same animation for multiple elements while still retaining circular motion for each.
See the Pen CSS Circular Motion Technique by Zach Saucier (@Zeaklous) on CodePen.
#6) Box shadow magic
For animations of simple no-content shapes, box-shadow
is quite useful. The box-shadow property can create multiple borders around elements. That idea, combined with some displacement, can create new animatable “elements” out of no additional HTML elements. This enables us to create the following animation, which appears to be six circular elements rotating circularly, but is in fact one element with some offset box-shadow shapes.
See the Pen Single element color loader by Zach Saucier (@Zeaklous) on CodePen
Sadly, percents are not supported by any box-shadow properties so they are not as easily responsive as a native HTML element. However they can still be changed manually in an animation or by using transform:scale(n)
on the actual HTML element which they are a part of.
#7) Using pseudo-elements
Similarly with box-shadows, pseudo elements can be used to add more content to the appearance of a single element. They can have separate animations from their parent, their own box-shadows, and are very similar to being child elements of without the HTML markup. This let’s us create amazing single element creations like the one below.
See the Pen Single Element gif Recreation by Zach Saucier (@Zeaklous) on CodePen
In the example, all of the large circles around the middle flashing circle, as well as two of the smaller circles on the rim (opposite from each other) are box-shadows on the main element. The other two small circles are part of a pseudo-element’s box-shadow and the ring made of dashes is an SVG applied as a background on the other pseudo element.
Some other things to note
Use transforms when you can
Transforms perform better than their non-transform counterparts as Paul Irish has shown (also). Primarily this means using scale and translate over changing the dimensions or top/left values.
Transforms also allow for more responsive design, allowing things such as scale
to be used relative to their original size, as is shown in this animation by Amos.
Not using transforms can also cause problems that are hard to catch. For example, in this animation of mine the elements were being colored incorrectly in Chrome although the values themselves were correct. After switching it to use transforms all my problems were solved.
z-index can cause problems
I probably spend more time fixing z-index
issues with my animations more than any other issue. Z-indexes are handled differently from vendor to vendor. In animations, the primary difference is that Mozilla does not animate z-index values, they have elements jump from one z-index to the next, whereas vendors like webkit do animate the z-index value.
Another thing to note is that if one wants their pseudo elements to appear behind their parent element, the pseudo element must have a negative z-index and the parent cannot have a stacking other than the default, which means you can’t apply a z-index or anything else that takes the parent out of its natural stacking context.
One last trick dealing with z-index is one that deals with opacity. Whenever an element is given an opacity other than the default “1”, it gains its own stacking context. For more information on this, check out Philip Walton’s post
Get inspired
Whether it’s something you see in the real world, an interesting web page that you find online, part of a video intro, a gif, or something else entirely, find things that you think may be possible to create and try to do so!
I have found that not looking at how the original author created it enables me to learn, to create it in a unique style, and sometimes even do it in a more efficient manor. Even if I end up failing at my original intention, I always become more comfortable with or learn more about the language I’m using. Often times I have something to show for it, even if it’s not as grand as I would had originally hoped. Other times I’m completely surprised by how awesome my creation is when I didn’t even mean for it to be!
I hope that this article helps you construct more awesome creations, even if you learned nothing from the specific techniques!
Wowsa… lovely stuff…
Great stuff, thanks! I think it’s worth mentioning that pseudo elements animation has really weak desktop browsers’ support and almost unsupported by mobile browsers. Cheers!
“Really weak desktop browser support” seems like a bit of a stretch.
IE has supported pseudo element animation as long as it has supported any animation (10+).
Chrome has supported it for a year, which is basically forever when you consider how fast Chrome users adopt new versions.
Firefox has supported it since early 2011.
Opera users with a version older than 15 are about 0.5% according to Statcounter.
Mostly it’s just old Safari hurting desktop (and mobile), but that should change since Safari 6.1 has been out for more than half a year.
Thanks for the cool post! All of these are awesome, some crazy stuff. But the first one with the flickering sign is REALLY cool and useful.
The #3 proportional animations is pretty awesome too. Crazy that it’s no javascript.
Can’t wait to play with some of these.
Gotta love CSS3 animations! It kind of surprises me that it’s not being used more though.
awesome… :D
So… What I’m hearing is pseudo-elements support animated Gallifreyan …
It does look like that doesn’t it? xD
Wow … amazing animations using CSS3…
Definate read and share. I am loving these guest posts more and more. Brilliant stuff chris. By thw way Chris, why don’t you have a share button on your posts.
Awesome!!!
This post is awesome tricks about css animation.
I did some practice on your #6) css magic.
Link is here: http://jsbin.com/afEGeGAq/2/
Oooof – very cool indeed! Might chief one or two of these for my own site, keep up the great work guys… thanking you :)
Wow… awesome stuff Zach. CSS3 is the future, no doubt!!
These are great. Now I request a follow-up post on incorporating fallbacks for those of us who need compatibility for IE9 and under.
I’m guessing use javascript to do some browser feature detection, and either animate with js or offer an alternative experience. But I’d love to see how someone like Chris or Zach would implement it.
The main reason for not creating the follow up article as you describe is that the javascript implementation of doing these things is more straightforward. Also, the purpose of this article is to spread awareness of some useful CSS tricks and to inspire. None of the demos were meant to be used without a good bit of customizing to put them into production.
Awesome !!
Woah! Seriously cool stuff. Thank you!
Wow that’s so cool… I love the animations, but that you could animate box-shadow shapes is new to me. This opens a host of animation opportunities. Awesome… going to play straight away with it.
Nice article, I didn’t even know that CSS can create such a wide variety of different animations:) You can almost say that “sky is the limit”.
WOW! This goes beyond everything I have seen.
that’s just awsome looking forward to see that magic in sass as well
This page crashes constantly on an iPhone (several browsers tried)
Nice Job!
Wow. Wonderful read! The most daunting thing for me about learning CSS animations has been, well, when browsing codepen, the SHEER AMOUNT OF CODE usually accompanying some of these things. I’ve started learning by looking at basic, waggling buttons and stuff, but I’m not sure I would have ever learned some of these tips and tricks on my own time.
Super exciting. Animations are the most game-y part of writing CSS. I only wish they came with achievements.
Great work! Second example remembers me my 3D pen:) http://codepen.io/haldunatar/pen/FDaot
Nice! I forked your work to create an illusion I had seen before, check it out!
Whoa! Never Realized you could set negative delay!
This would have been so useful for me a couple months ago.
I had a 30 second animation I had to watch over and over again to get just right! Could have just skipped to the end.
Good to know!
Thanks Zach!
I love it! Thanks!
These are AWESOME!
Sick!
Wow! These are amazing! I played around with animations recently on a small project, but this goes beyond anything I could have imagined. Very cool! Thanks for sharing!
That’s lovely! One recommendation: change it so the animation goes from
scale(.33)
(or whatever your proportion is) toscale(1)
instead of the opposite way. This will prevent the blurriness when it scales up (:You should put this on CodePen and send me the link, I’d love to fork this and work on it myself
The negative animation delay demo hurts my brain. And I like it ><
Excellent Tricks..
Oh My God! Wow! All desired tricks of CSS! No javascripts???!!! I love this! Can I copy the code pleaseeee …. :*
This is great! Unfortunately, animate css framework is very unstable in IE <9, and as sadly as it may be, a lot of people still use IE. Javascript still seems to reign in JQuery for all animates.
I wonder…if I coded a browser sniffer, would there be a way to apply these tricks to only compatible browsers and have an alternative for non-supporting browsers?
If that’s the case, I would love to do that for a client of mine that insisted on this css trick I implemented to get a paranormal activity movie intro effect
Paranormal Society of PA
Wow what beautiful animations, it’s amazing that they are made with pure css3
Very inspiring article, and definately something worth trying out.
Thank you.
There is a lot of potential in combining @keyframes and animation-fill-mode. Too bad there is no support in IE9. I like jQuery Transit (http://ricostacruz.com/jquery.transit/) a lot for the typical animations.
Truly amazing. Thank you for sharing.
CS-tricks.com always force me to stay on it. Nice work
The ERROR 404 is cool!
super… i like that Negative animation delays…its look like shake move
wonderful stuff Zack .. i am fall in love with this animations especially tha #7 .. Pseudo-elements … its looks pretty good .. great Imaginator zach ..