loading...

Why isn’t `0` a valid time value in CSS?

jandre3000 profile image Jan Drewniak ・3 min read

If you’ve ever written a CSS transition property like the one below:

.a {
    transition: translate 0 ease-out 0; 
}

You’ll notice that Devtools informs you that the CSS is invalid.

Rewrite that line adding the ms unit after the zero:

.a {
    transition: translate 0ms ease-out 0ms; 
}

And the CSS is fine and dandy.

So what’s the difference between 0 and 0ms?

The first value is a plain, unitless number (and let’s agree that zero is in fact a real number). In the CSS specification, numbers are referred to as numeric data types. The numeric data types in CSS include the following:

  • <length> type - (px, em, rem ...there’s a tonne)
  • <angle> type - (deg, grad, rad, turn)
  • <frequency> type - (Hz, kHz)
  • <resolution> type - dpi, dpcm, dppx

On Zero

But the unitless zero isn’t mentioned in any of those! The only mention of zero in the specification is a single line regarding length units:

For zero lengths the unit identifier is optional (i.e. can be syntactically represented as the <number> 0).

CSS Values 3, lengths

So this implies that you can only use a unitless Zero as a <length> unit. Ok... but why is that the case?

A bit of history

To understand why the unitless zero is only valid for length values and not others, we have to go beyond the spec and read some of the conversation around it.

Luckily, W3C conversations around the specification are all transcribed and recorded on public mailing lists. Here’s part of a meeting of the CSS Working Group from March 2016:

glazou: From author's perspective, 0 is 0 and you don't need a unit.
glazou: Did consider in the past.
glazou: Same argument for 0 vs 0px.
glazou: Should we make the same choice today?
glazou: Isn't 0 the same as 0deg?

And here’s another one from April 2017:

TabAtkins: A while back in a meeting I missed we decided to allow
unitless 0 for all angles because there were places
where impl allowed it. I don't think we did for all
dimensions.
fantasai: Correct.
TabAtkins: Even just on length vs angle it causes grammar
ambiguity
in motion where the shorthand can combine a
length and angle. In general this will become a
problem. Unitless 0 are a legacy mistake. This will
cause footguns in the future. I would like to revisit
the decision and make it unitless 0 angles in the
functions that allow them as a legacy thing and then
restrict to just lengths in grammars.

Hmmm... “Unitless 0 are a legacy mistake”? That sounds interesting. Could it be that the unitless zero is just a bad idea, and it works for lengths but not other number types because lengths were implemented first? Let’s take the unitless zero for a spin and see if it causes any “ambiguity or confusion in the grammars”.

Is unitless zero just a mistake?

Let’s take the animation example from MDN:

.a {
    /* @keyframes duration | timing-function | delay | 
    iteration-count | direction | fill-mode | play-state | name */
    animation: 3s ease-in 0s 0 reverse both paused slidein;
}

The full animation shorthand contains an iteration-count value, which is a unitless number. If unitless zeros were allowed for time values, it would look like this:

.a {
    animation: 3a ease-in 0 0 reverse both paused slidein;
}

Oh yeah, that does look confusing. See the 0 0? which is the time value and which is the iteration count?

So I guess, as Tab Atkins put it, the unitless zero in most cases is just a footgun.

Posted on by:

jandre3000 profile

Jan Drewniak

@jandre3000

Reading the specs so you don’t have too.

Discussion

markdown guide