You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-conditional-6] Behavior of style(0 = 0px) #12236
A literal 0 may be used for any numeric value where a unit would normally be expected, e.g. width: 0. Should this unitless behavior also work for style() range syntax? In other words, is style(0 = 0px) "false" due to a type mismatch, or is it "true"?
This was also discussed in #8376, and the consensus seems to be that 0 = 0px => "true" is the correct behavior. (cc @mirisuzanne ,@kizu)
There was also a question about whether or not we currently allow unitless zero in MQs with range syntax (@emilio), and the answer to that is "yes" (https://jsbin.com/taleroderi).
Note that in calculations, a unitless zero is not equivalent to a unit'd zero. Unitless zeros for lengths/angles are just an authoring convenience only allowed when used directly to satisfy a <length> (and in a few cases that explicitly call it out, an <angle>).
I'm supportive of 0 = 0px being a type mismatch and not being allowed.
(It's allowed in MQs because, given any particular MQ name, we know what the corresponding value type is, and thus can apply the normal "0 is allowed as a <length>" rule.)
The CSS Working Group just discussed [css-conditional-6] Behavior of style(0 = 0px), and agreed to the following:
RESOLVED: 0 and 0px are quivalent for conditions
The full IRC log of that discussion
<fantasai> andruud: Parser has behavior for <length> that you can supply 0 without unit
<fantasai> andruud: question came up during range queries, whether we should keep that behavior for comparison
<fantasai> andruud: e.g. is 0 = 0px for style queries?
<fantasai> andruud: zero is a number, 0px is a length, so not equal
<miriam> q+
<fantasai> andruud: in terms of consensus, it seems to be everyone against tab ;)
<emilio> q+
<kizu> q+
<astearns> ack miriam
<noamr> q+
<astearns> ack emilio
<oriol> q+
<fantasai> miriam: I don't have a strong opinion either, just unhappy that neither option is consistent across the board
<fantasai> emilio: I will side with Tab on this one
<fantasai> emilio: style queries are generally untyped
<lea> q?
<lea> q
<fantasai> emilio: and you have the same issue with calc(), don't know if zero is degrees length etc.
<lea> q+
<fantasai> TabAtkins: unitless zeros in calc() screw up figuring out the type of the calc()
<fantasai> TabAtkins: that doesn't apply here, just comparing two things
<fantasai> TabAtkins: We could go either way
<fantasai> emilio: for something like width > 0, you know width is a length
<fantasai> andruud: yeah, we'd need to do different special casing
<TabAtkins> like, is `calc(0 / 10px)`, is that unit 1/length, or just <number>?
<fantasai> TabAtkins: but you can use width > 0 in MQ
<fantasai> emilio: you know you're parsing a length at that point
<fantasai> TabAtkins: yes but because they're zeros...
<fantasai> emilio: implementable, not a big issue
<astearns> ack kizu
<fantasai> kizu: I think I want them ...
<fantasai> kizu: if you define custom registered property [missed]
<fantasai> kizu: for type, getting type of a custom property and you want to understand later on, you explicitly say "I'm checking the type on this"
<fantasai> kizu: but authors will expect 0 to 0px, so consistent for if() etc. to work this way
<astearns> ack noamr
<fantasai> noamr: aren't style queries also typed?
<kizu> https://codepen.io/kizu/pen/azvYVJw
<fantasai> noamr: can't we do something where if both values when parsed ...
<fantasai> TabAtkins: no, we don't necessarily know
<fantasai> noamr: they're all matching a property
<fantasai> TabAtkins: not necessarily, e.g. inside an 'if'
<astearns> ack oriol
<fantasai> oriol: I'm slightly more with Tab here
<fantasai> oriol: I could go either way for lenghts, but other dimensions that can accept unitless zeros so weird to accept
<astearns> ack lea
<fantasai> oriol: even for lenghts, lean more towards Tab, but it's a weak opinion
<fantasai> lea: My expectation is to compare the unitless zero to the other side
<fantasai> lea: if they're valid, then they should match
<fantasai> lea: e.g. zero for angles is not generally valid
<fantasai> lea: so would expect not to match in that case
<fantasai> lea: Where did we resolve to use style() for these comparisons
<astearns> ack fantasai
<astearns> fantasai: what lea said
<lea> q+
<fantasai> noamr: I think it would be sensible to start by shipping something more rigid, and then add type-based equivalence later, maybe more than just unitless zero
<lea> q-
<fantasai> astearns: that would be type coercion
<lea> q+
<lea> q- (sorry)
<fantasai> noamr: start with that and then do === later
<fantasai> noamr: more use cases than just unitless zero
<astearns> s/be type/be explicit type/
<astearns> ack lea
<fantasai> lea: My concern is case where you have a custom property (token stream) and then you register as a length, and now it stops matching
<fantasai> lea: would be better if consistent with how lengths generally work
<astearns> ack fantasai
<astearns> fantasai: from a user perspective we’re used to 0 = 0px
<lea> +1
<TabAtkins> I would be okay with a literal 0 allowing matching against a 0 <number> *or* a 0 <length>
<TabAtkins> but a calculated 0 shouldn't be, maybe?
<ydaniv> +1 to fantasai
<miriam> +1 (but that inconsistency is already confusing people in calc)
<TabAtkins> 1. calc()-consistency, 0 != 0px
<TabAtkins> 2. property-consistency, 0 == 0px (but no other unit)
<fantasai> TabAtkins: it is the case that calc(0) is invalid in [missed], so it would have to be a literal zero
<TabAtkins> s/missed/width prop/
<fantasai> astearns: Proposed resolution that literal zero does equal a 0 length for conditions
<fantasai> astearns: Anyone want to argue against?
<fantasai> astearns: Anyone want to object?
<fantasai> RESOLVED: 0 and 0px are quivalent for conditions
<TabAtkins> (making clear, i mistyped above; "no other type", not "no other unit". 0 == 0rem, too)
Activity
andruud commentedon May 27, 2025
Perhaps we don't need to spend call time on this detail.
Proposed async resolution:
A unitless zero matches any numeric data type in range queriesLoirooriol commentedon May 30, 2025
Any numeric data type? Like
0 = 0degeven though<angle>doesn't accept unitless 0? Seems weird to me.Crissov commentedon May 30, 2025
<hue>does, though.andruud commentedon Jun 2, 2025
OK, I guess we do need to spend call time on it.
tabatkins commentedon Jun 26, 2025
Note that in calculations, a unitless zero is not equivalent to a unit'd zero. Unitless zeros for lengths/angles are just an authoring convenience only allowed when used directly to satisfy a
<length>(and in a few cases that explicitly call it out, an<angle>).I'm supportive of
0 = 0pxbeing a type mismatch and not being allowed.(It's allowed in MQs because, given any particular MQ name, we know what the corresponding value type is, and thus can apply the normal "0 is allowed as a
<length>" rule.)css-meeting-bot commentedon Aug 20, 2025
The CSS Working Group just discussed
[css-conditional-6] Behavior of style(0 = 0px), and agreed to the following:RESOLVED: 0 and 0px are quivalent for conditionsThe full IRC log of that discussion
<fantasai> andruud: Parser has behavior for <length> that you can supply 0 without unit<fantasai> andruud: question came up during range queries, whether we should keep that behavior for comparison
<fantasai> andruud: e.g. is 0 = 0px for style queries?
<fantasai> andruud: zero is a number, 0px is a length, so not equal
<miriam> q+
<fantasai> andruud: in terms of consensus, it seems to be everyone against tab ;)
<emilio> q+
<kizu> q+
<astearns> ack miriam
<noamr> q+
<astearns> ack emilio
<oriol> q+
<fantasai> miriam: I don't have a strong opinion either, just unhappy that neither option is consistent across the board
<fantasai> emilio: I will side with Tab on this one
<fantasai> emilio: style queries are generally untyped
<lea> q?
<lea> q
<fantasai> emilio: and you have the same issue with calc(), don't know if zero is degrees length etc.
<lea> q+
<fantasai> TabAtkins: unitless zeros in calc() screw up figuring out the type of the calc()
<fantasai> TabAtkins: that doesn't apply here, just comparing two things
<fantasai> TabAtkins: We could go either way
<fantasai> emilio: for something like width > 0, you know width is a length
<fantasai> andruud: yeah, we'd need to do different special casing
<TabAtkins> like, is `calc(0 / 10px)`, is that unit 1/length, or just <number>?
<fantasai> TabAtkins: but you can use width > 0 in MQ
<fantasai> emilio: you know you're parsing a length at that point
<fantasai> TabAtkins: yes but because they're zeros...
<fantasai> emilio: implementable, not a big issue
<astearns> ack kizu
<fantasai> kizu: I think I want them ...
<fantasai> kizu: if you define custom registered property [missed]
<fantasai> kizu: for type, getting type of a custom property and you want to understand later on, you explicitly say "I'm checking the type on this"
<fantasai> kizu: but authors will expect 0 to 0px, so consistent for if() etc. to work this way
<astearns> ack noamr
<fantasai> noamr: aren't style queries also typed?
<kizu> https://codepen.io/kizu/pen/azvYVJw
<fantasai> noamr: can't we do something where if both values when parsed ...
<fantasai> TabAtkins: no, we don't necessarily know
<fantasai> noamr: they're all matching a property
<fantasai> TabAtkins: not necessarily, e.g. inside an 'if'
<astearns> ack oriol
<fantasai> oriol: I'm slightly more with Tab here
<fantasai> oriol: I could go either way for lenghts, but other dimensions that can accept unitless zeros so weird to accept
<astearns> ack lea
<fantasai> oriol: even for lenghts, lean more towards Tab, but it's a weak opinion
<fantasai> lea: My expectation is to compare the unitless zero to the other side
<fantasai> lea: if they're valid, then they should match
<fantasai> lea: e.g. zero for angles is not generally valid
<fantasai> lea: so would expect not to match in that case
<fantasai> lea: Where did we resolve to use style() for these comparisons
<astearns> ack fantasai
<astearns> fantasai: what lea said
<lea> q+
<fantasai> noamr: I think it would be sensible to start by shipping something more rigid, and then add type-based equivalence later, maybe more than just unitless zero
<lea> q-
<fantasai> astearns: that would be type coercion
<lea> q+
<lea> q- (sorry)
<fantasai> noamr: start with that and then do === later
<fantasai> noamr: more use cases than just unitless zero
<astearns> s/be type/be explicit type/
<astearns> ack lea
<fantasai> lea: My concern is case where you have a custom property (token stream) and then you register as a length, and now it stops matching
<fantasai> lea: would be better if consistent with how lengths generally work
<astearns> ack fantasai
<astearns> fantasai: from a user perspective we’re used to 0 = 0px
<lea> +1
<TabAtkins> I would be okay with a literal 0 allowing matching against a 0 <number> *or* a 0 <length>
<TabAtkins> but a calculated 0 shouldn't be, maybe?
<ydaniv> +1 to fantasai
<miriam> +1 (but that inconsistency is already confusing people in calc)
<TabAtkins> 1. calc()-consistency, 0 != 0px
<TabAtkins> 2. property-consistency, 0 == 0px (but no other unit)
<fantasai> TabAtkins: it is the case that calc(0) is invalid in [missed], so it would have to be a literal zero
<TabAtkins> s/missed/width prop/
<fantasai> astearns: Proposed resolution that literal zero does equal a 0 length for conditions
<fantasai> astearns: Anyone want to argue against?
<fantasai> astearns: Anyone want to object?
<fantasai> RESOLVED: 0 and 0px are quivalent for conditions
<TabAtkins> (making clear, i mistyped above; "no other type", not "no other unit". 0 == 0rem, too)