[css-values] Define value syntax that limits <integer>, <number>, <length>, etc. to ranges #355
Many properties only accept positive values. Negative values are illegal, and are parse errors. This is currently only defined in prose for the relevant property. Examples: width, height, line-height.
In contrast, other properties have logical bounds, but values outside these bounds are parsed as normal and only clamped at used value time. Examples: opacity, numeric parameters in color functions.
I'm sure it would be useful for both authors and implementers if the property value syntax explicitly indicated whether negative values would be a parse error or not. That requires new value types in CSS Values & Units.
I'm not sure if there are any other common "illegal value" restrictions currently defined in prose, but it's worth looking around to see if there are, and if they can also be standardized into the value definition syntax.
The text was updated successfully, but these errors were encountered:
Well, "positive" is only allowed for integers, not numbers or dimensions, because it constitutes an open range otherwise, which is informally disallowed. We do use non-negative (sometimes paired with prose that floors it at some non-zero value), but that's harder to express easily.
Mathematically, "positive" usually means zero or greater, which is what I was thinking of, although depending on how the CSS parser handles -0, you might need some extra text in there.
"non-zero positive integer" would be another possible type, if that's actually required anywhere.
That's not really true in my experience? Zero is neither positive nor negative, and there's a lot of stuff backing that up: the relatively common usage of "non-negative" in precise technical contexts, the implementations of sign() functions in various languages, the fact that +0 and -0 are mathematically equivalent, etc. CSS has been pretty precise about this, because we've gotten bug reports about "why isn't 0 valid?" when we were imprecise and just used "positive". At best, whether 0 is considered "positive" or not is ambiguous and context-sensitive.
OK, I agree that a completely unambiguous terminology would be better. But the rest of my suggestion still stands: can we define
I don't have a problem with this in theory, but in practice
Yes, I'm certainly not stuck on the syntax. I just want the full parsing requirements to be unambiguously defined by the grammar.
Another approach would be to express it numerically, something like
You could use more vulgar terms. They come with varying definitions outside CSS, but would of course have an unambiguous one inside:
Thinking @AmeliaBR's latest idea further,
The discussion on clamping column width values (#1741) made me think of this again.
One final option for terminology: Take a cue from WebIDL, and use "unsigned" for values that cannot be negative. So it would be
That said, I still think I prefer an explicit constraints syntax, like
Regardless of the syntax, I still would very strongly like to add this option to the CSS grammar, so that all parser constraints on values can be expressed in the grammar.
So, I'm requesting this for the WG agenda, with the following questions for discussion:
If we can get a resolution on those points, then we can bikeshed the exact syntax in a more focused way.
The Working Group just discussed
The full IRC log of that discussion<dael> Topic: Define <positive-integer>, <positive-number>, <positive-length>, etc. sub-types
<dael> github: https://github.com//issues/355
<dael> AmeliaBR: A couple years ago there was discussion and it got lost in bikeshedding syntax. I wanted to at least get a clear opinion from the group if the idea is good.
<dael> AmeliaBR: I'd like to see if that when we have properties with constraints enforced by the parser, most common is no negative values, there is a way to explain that in the grammar rather then only prose.
<dael> AmeliaBR: It would be convenient for people impl parsers if the grammar covered everything esp now that Houdini is exposing the value syntax. Might be time to be more strict about value definition language.
<florian> +1, makes total sense to me
<dael> AmeliaBR: I was hoping to get a resolution that it would be a good idea to extend value definition lang to cover all constraints from the parser.
<dbaron> "all constraints that can be enforced by the parser" sounds like it might be a little much
<dael> AmeliaBR: I had a second question on narrowing down approaches.
<astearns> +1 from me as well
<dael> fantasai: I don't think we'll be able to put in all parsing restrictions because I remember there are restrictions not in the grammar that aren't just about limiting range of numbers. We won't get to 100% but it should be possible to put range restrictions. If this is author exposed syntax that might be important.
<TabAtkins> positive-int, and gez-int and gez-number seem very fine, along with gez-length/etc
<astearns> define gez?
<dael> florian: I think we could take somewhere between...in V&U we define non-negative ranges and houdini relies on that. If it's not the case already in indiviual specs we have something that looks like int but with constraints we deinfe anew type. Doesn't have to be shared in V&U. That's not actionable, that's how to write. The actionable part I'm all for it.
<TabAtkins> p-integer, nn-integer
<dael> astearns: I'm all for having this defined in the grammar and not lost in the prose. I don't care what names we use particularly.
<dael> fantasai: I'd like the syntax to be reasonably readable and not so long that the grammar is hard to read. non-negative-integrer is really long.
<dael> fantasai: Every time we throw in one of these it wraps and it's hard to read. It seems like a great idea but I haven't seen a proposal for yes we should do it this way. If this is exposed in Houdini we should put thought in understandable and usable like we do for other property values we define.
<fantasai> s/one/one or four/
<dael> astearns: I think consensus is this is a good direction to take. Second question?
<fantasai> s/wraps/gets long and maybe wraps/
<dael> AmeliaBR: My initial idea was new name types but in the discussion there was a suggestion of introducing it more as a modifying constraint within the type. Syntax that looked readable was make it look like a HTML attribute.
<dael> AmeliaBR: It's very nice and readable. Other aspect is it's open ended. Could be a benefit, could be a negative. Do people like the idea of adding a general way of adding constraints or is it something we want to keep to named types?
<dael> TabAtkins: I hadn't seen that comment, I'll have to think about that.
<florian> I am not sure, but I am intrigued
<dael_> astearns: prop: we will add more terms tot he grammar to describe value ranges and such, but approach is in the air.
<dael_> astearns: Objections?
<fantasai> proposed resolution: Extend value definition syntax to handle value ranges and possibly other syntactic restrictions, syntax TBD
<dael_> RESOLVED: Extend value definition syntax to handle value ranges and possibly other syntactic restrictions, syntax TBD
<dbaron> I need to head out now, but I'll see you next week...
FYI, I found a case of a numeric property defined to have a fixed range that isn't just non-negative or strictly positive.
Of course, only one browser (Firefox) currently implements that exact rule as a parser-time check, see w3c/svgwg#545
Edit: as described in the linked issue, the property is now defined to accept any non-negative value.
I'd like to get a resolution on this at the February F2F.
Specifically, I'm advocating for the syntax that uses SGML-style attributes (
I haven't had a chance to do a comprehensive review of how many properties this would effect, but here are some examples from CSS Fonts Level 4:
As discussed previously, this syntax only covers parser-enforced restrictions on values, not clamping that happens at computed-value or used-value time. Specifically, any value that doesn't meet these constraints on the data type would make the surrounding declaration invalid, per CSS Syntax:
Currently, the parser-level constraints on CSS values are defined by prose that states that certain values are invalid. E.g., the prose for
The proposed change would encode those constraints directly in the CSS Values grammar.
I'd prefer to use mathematical range notation. It's a lot more compact, and part of keeping these grammars readable is keeping them compact enough to be visually parsed.
Alternately some form of colloquial range notation (same rationale).
(Maybe replace "to" with a proper n-dash. ;)
@fantasai Okay, so that's two additional syntaxes, for three alternatives so far.
So people can really compare, here's what they look like for the font properties I used in my comment above, along with my summary of pros and cons:
Bracket range notation
Human-readable range notation
Nope. The whole idea is to make a grammar that is easier to auto-parse! Subtle typographic niceties not allowed! Especially because I want to eventually use the chosen syntax within author-supplied values to Houdini APIs.
Would it be troublesome to do
Brackets and dots notation
An ellipsis made of three dots
This could be coupled with two dots to indicate a closed range, which in turn is just a variation of the human-readable range notation with
The CSS Working Group just discussed
The full IRC log of that discussion<gregwhitworth> Topic: Adding min/max constraints
<gregwhitworth> AmeliaBR: currently we have something like length-percent and in the prose it says negative values are invalid
<astearns> github: https://github.com//issues/355#issuecomment-458324757
<gregwhitworth> AmeliaBR: the idea is to get that into the actual syntax grammar
<gregwhitworth> AmeliaBR: especially with various houdini APIs we're providing authors with access to the syntax
<gregwhitworth> AmeliaBR: the issue is to discuss what this syntax looks like
<gregwhitworth> AmeliaBR: my proposal was to look like something like sgml attributes, we're using angle brackets for data types
<gregwhitworth> AmeliaBR: fantasai concern is that that can get verbose
<gregwhitworth> AmeliaBR: if you go down to the second to last issue I have the different options with 4 real world examples
<gregwhitworth> AmeliaBR: Any pros/cons - I've listed mine but would like to hear peopl'es feedback
<gregwhitworth> fantasai: I like my proposal
<gregwhitworth> fantasai: I really don't want to make things too verbose, the more the grammar has to wrap the harder it is to read
<gregwhitworth> fantasai: I
<gregwhitworth> fantasai: I prefer the more human readible version
<gregwhitworth> TabAtkins: shows options on screen
<gregwhitworth> TabAtkins: explains the various proposals in the link above
<gregwhitworth> fantasai: a min in human readible could be 0+
<gregwhitworth> TabAtkins: I'm most a fan of the bracket range syntax
<gregwhitworth> fantasai: if you're going to use multipliers it uses similiar syntax
<gregwhitworth> TabAtkins: this is already in the syntax
<gregwhitworth> TabAtkins: I agree with the idea in general
<gregwhitworth> TabAtkins: I agree with AmeliaBR that with Houdini we need to provide access to this
<gregwhitworth> heycam: A non syntax question
<gregwhitworth> heycam: when we have prose that restricts these values, when we have calc expressions, when we have negative inside the calc - would a change to this syntax make some values invalid earlier?
<gregwhitworth> TabAtkins: This shouldn't change anything this is just moving the prose into the grammar
<gregwhitworth> TabAtkins: calcs are still valid and clamp to the range
<gregwhitworth> heycam: if you have a property number 1-1000
<gregwhitworth> heycam: and you use any calc inside that
<gregwhitworth> TabAtkins: yep, that should work
<gregwhitworth> astearns: does anyone have any objections to bracket notation
<gregwhitworth> astearns: I would prefer to have explicit rather than empty
<gregwhitworth> TabAtkins: what about writing infinity rather than the symbol
<gregwhitworth> fantasai: no
<gregwhitworth> iank_: are we allowing the word infinity?
<gregwhitworth> TabAtkins: what about both?
<gregwhitworth> iank_: I'm fine with both
<gregwhitworth> AmeliaBR: that sounds the best for me
<gregwhitworth> AmeliaBR: the infinity symbol is nice in a spec but not necessarily for typing in code
<myles_> +1 to what AmeliaBR said
<gregwhitworth> heycam: rather than brackets and commas you can use ..
<gregwhitworth> TabAtkins: some languages include two dots others use three dots
<gregwhitworth> gregwhitworth: I would prefer no on that
<gregwhitworth> AmeliaBR: as fantasai noted the brackets are known in CSS in the grammar
<gregwhitworth> iank_: also the ... may get confused with the destructioring in JS
<gregwhitworth> TabAtkins: we will go with the bracket version and allow Infinity and the infinity symbol
<gregwhitworth> TabAtkins: I would never propose the inifinty symbol for CSS itself, this is for syntax
<gregwhitworth> florian: Bikeshed feature request, convert infinity word to symbol
<gregwhitworth> fantasai: there is an infinity code and ampersand version
<gregwhitworth> fantasai: what's the case sensitivity of the inifnity keyword?
<gregwhitworth> TabAtkins: in JS it's Infinity
<gregwhitworth> fantasai: as a string?
<gregwhitworth> TabAtkins: it would be number [1, Infinity]
<AmeliaBR> Proposal: Use the bracket range notation (from the issue), but with infinite ranges (no max/min) represented by either `Infinity` or ∞ (or negative thereof)
<gregwhitworth> AmeliaBR: it's not a string it's a token within the syntax
<gregwhitworth> fantasai: question, is our sytax types case sensitive
<gregwhitworth> TabAtkins: the Houdini syntax cares
<gregwhitworth> fantasai: yeah we're consistent in our specs but I was curious
<gregwhitworth> astearns: any objections to the proposal
<TabAtkins> `syntax: "big | BIGGER"` in registerProperty() is already case-sensitive
<gregwhitworth> RESOLVED: We will use the bracket range notation
…efinition syntax. #355
Ok, change of plans. I decided it's just as easy to make the edits as to make a few dozen issues. But I came up with a stylistic question:
Should I only be adding the bracket range notation to the blue-box definition, or also to prose references to syntax parts? I'm currently adding it in where there is a definition list that breaks out the syntax pieces, but am not otherwise adding it to prose.
I'm also leaving in all the prose restrictions (e.g. "negative values are invalid" or "negative values are not allowed").
I'm copying it to the
I am removing prose restrictions that are entirely obviated by the grammar change, tho; we don't say in prose that a value "must be a length, or else it's invalid", etc., so when the grammar expresses that it's non-negative, no need to say that explicitly again in prose.