The Importance of “s” in CSS3 Transition Shorthand
On a recent project, I spent the better part of an hour (okay, maybe longer) fighting with what I would learn is an interesting anomaly in the way that Firefox (4 and 5) deal with CSS3 shorthand transition notation. What baffled me was the fact that the other players, Webkit (Safari and Chrome) and Opera browsers, worked properly (or least what I thought was proper) with the exact same code. The premise was to have an area with a fixed height, set to overflow: hidden, but then allow the site navigation to scroll (transition) to the proper anchor, resizing the content box’s height to accommodate the contents while keeping the other contents hidden.
To illustrate the problem, have a look at this simplified example:
Sed do eiusmod tempor incididunt ut enim ad minim veniam, excepteur sint occaecat. Quis nostrud exercitation ullamco laboris nisi lorem ipsum dolor sit amet. Mollit anim id est laborum. Consectetur adipisicing elit, ut enim ad minim veniam, eu fugiat nulla pariatur. In reprehenderit in voluptate qui officia deserunt sunt in culpa.
Duis aute irure dolor ut enim ad minim veniam, velit esse cillum dolore. Quis nostrud exercitation. Ut labore et dolore magna aliqua.
Velit esse cillum dolore ut enim ad minim veniam, ullamco laboris nisi. Duis aute irure dolor sed do eiusmod tempor incididunt lorem ipsum dolor sit amet. Velit esse cillum dolore qui officia deserunt ut labore et dolore magna aliqua.
Mollit anim id est laborum. Ut aliquip ex ea commodo consequat. Eu fugiat nulla pariatur.
Ut enim ad minim veniam, velit esse cillum dolore qui officia deserunt. Sunt in culpa. Ullamco laboris nisi ut enim ad minim veniam, ut aliquip ex ea commodo consequat. Ut labore et dolore magna aliqua. Sunt in culpa consectetur adipisicing elit, mollit anim id est laborum.
Sed do eiusmod tempor incididunt ut enim ad minim veniam, excepteur sint occaecat. Quis nostrud exercitation ullamco laboris nisi lorem ipsum dolor sit amet. Mollit anim id est laborum. Consectetur adipisicing elit, ut enim ad minim veniam, eu fugiat nulla pariatur. In reprehenderit in voluptate qui officia deserunt sunt in culpa.
Duis aute irure dolor ut enim ad minim veniam, velit esse cillum dolore. Quis nostrud exercitation. Ut labore et dolore magna aliqua.
Velit esse cillum dolore ut enim ad minim veniam, ullamco laboris nisi. Duis aute irure dolor sed do eiusmod tempor incididunt lorem ipsum dolor sit amet. Velit esse cillum dolore qui officia deserunt ut labore et dolore magna aliqua.
Mollit anim id est laborum. Ut aliquip ex ea commodo consequat. Eu fugiat nulla pariatur.
Ut enim ad minim veniam, velit esse cillum dolore qui officia deserunt. Sunt in culpa. Ullamco laboris nisi ut enim ad minim veniam, ut aliquip ex ea commodo consequat. Ut labore et dolore magna aliqua. Sunt in culpa consectetur adipisicing elit, mollit anim id est laborum.
The two columns of text each have a transform: translateY(-100px);
applied to them on :hover. Additionally, they are both set to transition the effect – thereby “scrolling” the text up by 100px. Simple enough. And if you are looking at this in anything other than Firefox, both columns behave the same. Of course, if you are looking in Internet Explorer, you won’t see anything because even with IE9, transforms are not supported. UPDATE: I’ve added the -ms- prefix for transforms/transitions, and in IE10 this works as it does in the other standards-compliant browsers.
Being that I like to write CSS shorthand when possible (but am moving back away from it for many CSS3 techniques, especially backgrounds), I wrote the transition line in shorthand. Simply transition: transition 2s linear 0;
(with the browser specific code omitted for the moment). Testing in Webkit (which is what I use as my initial dev environment browser) showed everything was working properly. So, of course, I didn’t think more about it until the project was basically complete and I began the round of testing in Firefox, Opera and, yes, IE.
I knew that IE was not going to perform the “scroll”, but I was completely shocked to discover that FF was simply “jumping” (as you can see in the left column of the example) – exactly the same behavior as IE. I scratched my head in wonder as I ran over to CanIUse.com to make sure that my summer vacation in the Caribbean sun hadn’t confused my recollection about FF’s support of the transition property. I was completely baffled, and, in an effort to get to the bottom of the issue, I broke the shorthand out – going from -moz-transition: -moz-transform 2s linear 0;
to
-moz-transition-property: -moz-transform;
-moz-transition-duration: 2s;
-moz-transition-timing-function: linear;
-moz-transition-delay: 0;
And suddenly things appeared to be working in FF. This is also what you see above. The left column uses shorthand, the right column uses the longhand notation.
Okay, the simple assumption was Firefox doesn’t support shorthand – but I knew for a fact that that couldn’t be. After looking at the code for the umpteenth time, I was as baffled as when I wrote it. But a shout-out on the Twitters revealed the answer… no “s”.
The “0″ at the end of the shorthand doesn’t have a unit. And with that, Firefox fails to execute the entire line. But wait, the longhand version doesn’t have a unit, so what gives?! Well, that line is actually being ignored as well. But because it’s longhand, the property, duration and timing-function are all being executed. To confirm, I changed the -delay property in the longhand version and, sure enough, no delay. Going back to the shorthand version, I added the “s” to the “0″, and, problem solved!
Of course, this begs the question “why”, which a number of us spent Sunday afternoon discussing on the Twitters. Tab Atkins confirmed that, in fact, the spec requires the unit on instances of time. So, actually, the problem isn’t a Firefox issue, but rather the fact that Chrome, Safari and Opera are “allowing” us to be slack in our code. Hmm. My position is, the default is “0s”, and in no other instance am I required to type the unit when specifying “0″, so why do I have to here? But who listens to me anyway?!
I happily added the stupid “s” and will definitely never make that mistake again… Oh, and I invoiced myself for several lost hours and frustration…! We’ll see if I pay the bill. ;-)
August 16th, 2011 at 5:16 pm
Interesting that units are required on time instances, but not on anything else (like top/left values). Wonder why that’s the case… 0 is 0, it shouldn’t need a unit!
August 16th, 2011 at 5:35 pm
I completely agree, FWIW.
August 21st, 2011 at 5:27 am
Thanks for this. I would have gone through the same frustrating process had it not been for your work ;)
August 21st, 2011 at 10:24 am
old, btw unit is required according to w3c spec.
August 21st, 2011 at 10:39 am
The point is “why” is the unit required when declaring “0″ – which is also the default. You can leave it off completely and the transition plays fine. In other words, the fact that transition-delay and transition-duration require a unit when set to zero is not consistent with the rest of the CSS specification.
October 27th, 2011 at 11:55 pm
Hi Just viewed your video http://tv.adobe.com/watch/max-2011-design/from-web-to-mobile-to-app-in-60-seconds-dreamweaver-cs55/ It was an awesome experience to learn jquery. Can u help me on one issue. Saw the mobile and ipad css versions you showed on the video of a sample website.I Cant understand how build mobile or ipad version css out of my website http://radhavallabh.com which I created using Dreamweaver. I am no expert so Your steps would be very much helpful and appreciated
March 21st, 2012 at 9:39 pm
“Simply ‘transition: transition 2s linear 0;’… (with the browser specific code omitted for the moment). ”
Just clarifying from above. Are you transitioning a transition??
Or should that be transform?