You already know that inline styles are “bad practice.” Inline styles aren’t reusable like CSS in separate files is, and thus, inefficient bloat. Unless of course, when it isn’t. There are some instances where inline styles make perfect sense. Perhaps you have an application where user’s pick their favorite color, and then you set the background of the body to that. Using an inline style in that case is actually more efficient than external CSS, since it’s specific to one user and one element.
Now let’s say you want to animate to a value set in an inline style. Say you want to animate a progress bar. You start at zero, and need to go up to any arbitrary value. Perhaps a call to the server tells you how complete an upload is and you set the value from that.
In a post I did nearly a year ago, I lamented that you can’t animate to an inline style. You can’t declare a keyframe in inline styles and you don’t know what final value to animate to in the external CSS. Alas I was wrong, as I didn’t know about this bonafide little CSS trick.
<div class="progress-bar">
<div style="width: 75%">Upload is 75% complete.</div>
</div>
Here’s the trick: just omit the to
or 100%
declaration from the @keyframe:
@-webkit-keyframes progress-bar {
0% { width: 0; }
}
@-moz-keyframes progress-bar {
0% { width: 0; }
}
keyframes progress-bar {
0% { width: 0; }
}
Then you call the animation on the progress bar:
.progress-bar > div {
-webkit-animation: progress-bar 2s;
-moz-animation: progress-bar 2s;
animation: progress-bar 2s;
}
And just like that, the progress bar will animate itself up to the value set by the inline style.
See the Pen Animate to an Inline Style by Chris Coyier (@chriscoyier) on CodePen.
Special thanks to Michael Paryna who emailed me about this and got me to give it a try.
That’s cool.
I’ll find a use for it somewhere.
You know what, I thought I knew all there was to know about CSS animation! Good work finding this Chris!
I was messing with your Dabblet link and the animation breaks through the containing div when you set the inline style to width: 100%; I tried setting it to width: auto, but that won’t trigger the animation. I also tried setting the body padding:0px and still breaks… Any ideas?
If you set the width to 100% for the progress element, then you have to change the padding on the progress element, not the padding on the body. The problem is, “width: 100%” doesn’t really do what we want it to do. I wrote about that problem here.
In this case, though, with the padding removed, the text looks awkward, so I fixed it by adding a paragraph element on which you can safely add padding (because the paragraph doesn’t have a set width):
http://dabblet.com/gist/1687523
And while typing this comment, I realized that you can fix this even quicker with
box-sizing
, so one line fixes it here, with no paragraph element:http://dabblet.com/gist/1687552
That is due to the box model (the padding is the culprit). It’s easily fixed by using
box-sizing: border-box;
(this will work in IE7 and above, but you will need to use webkit and moz prefixes).This is also provides a way to animate something on inital load of a page, without any other state changes like click or hover. I remember researching that recently and the general consensus was that you couldn’t. But you probably knew otherwise anyway…
Shouldn’t that be a progress element? Great trick though.
I’d say yes but it’s SO hard to style <meter> and <progress> still. Let alone animate. When we gettin’ proper shadow dom for that? ;)
See here:
http://blog.oldworld.fr/index.php?post/2011/07/The-HTML5-progress-element-in-Firefox
http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/
Maybe can be used with jquery and “on.load” like :
Only if we know the page loading time…
Adam Khoury from developphp.com did something recently on this, he used JavaScript and HTML5 together to create an animated uploader. Here is the link to his video lesson http://www.developphp.com/view.php?tid=1228
Woops, that’s developphp.com
Sorry for the mis-link! :P
That’s nice, but that’s how it’s always been done. The cool thing here is that it’s pure CSS.
that’s Awesome, well explained… thanks for sharing it…
That’s pretty awesome.
I love that you’ve taken a mistake you made a year ago and turned it into another awesome blog post :)
There’s more than CSS Tricks to be learned from you.
Hi, Chris, I also posted something similar few days ago ^_^
Oooh!
That looks really nice! Bookmarked.
Although…I can see a wee glitch in Chrome. The striped overlay is ‘over’ of the rounded bar. So the mask is broken I guess.
Yeah, I don’t know why. I’ve added
overflow:hidden
but still not working T_TDo I have to use
relative
positioning insteadabsolute
?Edit: I only applied the absolute position on the pseudo element, while elements in it didn’t modified. That’s what makes me confused about why
overflow:hidden
isn’t working.that wasn’t something interesting .. please learn how to make an uploading progress using PHP and JS .. or something like that ..
Great share, I’m going to have to try this out in the future. CSS animation is awesome.
Cool i like it, htanks
I styled it a bit and came up with this:
Dabblet
Use `overflow: hidden;` for `.progress-bar` http://dabblet.com/gist/1697531
This bit might be handy to add to the inner div
very cool. cheers for the help!
Hi Chris, I also posted something similar few month ago…
Progress Bar CSS3
The process is slightly different.
These are nice. This is the exact scenario I was talking about though. In your case you have to know what % you are animating to in the external CSS. Kinda cool to just set that value as an inline style instead.
Thank you so much for this tutorial! I really learned some new great tricks.
I love your tutorials and your clean layouts.
Wow… this is great…, but how about IE browser? work?
Microsoft will begin to support CSS3 animations on IE10 Windows 8.
For older browsers that doesn’t support for CSS3 animations you can use for JavaScript feedback.
Really nice I like it .I love your tutorials and your clean layouts.
I love how you’re using dabblet all over the place in your CSS demos. Really awesome app!
Is it possible to animate to the inline style at, let’s say, 50% of the animation?