Skip to content

[css-values] Define value syntax that limits , , , etc. to ranges #355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AmeliaBR opened this issue Jul 28, 2016 · 25 comments
Closed

[css-values] Define value syntax that limits , , , etc. to ranges #355

AmeliaBR opened this issue Jul 28, 2016 · 25 comments

Comments

@AmeliaBR
Copy link
Contributor

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.

@tabatkins
Copy link
Member

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.

@AmeliaBR
Copy link
Contributor Author

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.

@frivoal
Copy link
Collaborator

frivoal commented Jul 29, 2016

"non-zero positive integer" would be another possible type, if that's actually required anywhere.

It is: #341 (comment)

@astearns astearns added the css-values-4 Current Work label Jul 29, 2016
@tabatkins
Copy link
Member

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.

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.

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Aug 3, 2016

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 , , etc., data types, so that these restrictions do not have to be defined in prose?

@fantasai
Copy link
Collaborator

fantasai commented Oct 24, 2017

I don't have a problem with this in theory, but in practice eats up a much larger part of the measure. For grammars with more than a handful of possible value components, it triggers more wrapping and makes them harder to read. So while defining these limits in prose is maybe not ideal, I'm less than enthusiastic about adopting these new types. :(

@tabatkins
Copy link
Member

We can go with shorter names; , , etc. Unsure if that's worthwhile.

@AmeliaBR
Copy link
Contributor Author

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 = 0>, 0>, except without > characters! and ?

@Crissov
Copy link
Contributor

Crissov commented Oct 25, 2017

You could use more vulgar terms. They come with varying definitions outside CSS, but would of course have an unambiguous one inside:

  • ℤ = ,
  • ℕ = , – either positive or non-negative
  • ℕ* = ℕ⁺ = ℕ₁ = ℤ⁺ = {1, 2, 3, …}: , , , … – positive
  • ℕ⁰ = ℕ₀ = {0, 1, 2, …}: , , , , , , … – non-negative

Thinking @AmeliaBR's latest idea further, , , show different syntax that should be readable instantly for many people.

@AmeliaBR
Copy link
Contributor Author

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 , , , etc. For the rare cases: .

That said, I still think I prefer an explicit constraints syntax, like , as it is easier to understand on its own.

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:

  • Should the CSS Value Definition Grammar be expanded to allow it to express all parser-level constraints on allowed values?

  • If so, how should the constraints be expressed?

    1. By adding new data type names for all existing constrained types (non-negative numbers, non-negative lengths, strictly positive integers, etc.)?
    2. Or, by adding a generic way of indicating maximum and minimum values for any numeric type?

If we can get a resolution on those points, then we can bikeshed the exact syntax in a more focused way.

@css-meeting-bot
Copy link
Member

The Working Group just discussed Define , , , etc. sub-types, and agreed to the following resolutions:

  • RESOLVED: Extend value definition syntax to handle value ranges and possibly other syntactic restrictions, syntax TBD
The full IRC log of that discussion Topic: Define , , , etc. sub-types
github: https://github.com//issues/355
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.
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.
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.
+1, makes total sense to me
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.
"all constraints that can be enforced by the parser" sounds like it might be a little much
AmeliaBR: I had a second question on narrowing down approaches.
+1 from me as well
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.
positive-int, and gez-int and gez-number seem very fine, along with gez-length/etc
define gez?
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.
greater-equal-zero
p-integer, nn-integer
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.
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.
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.
s/one/one or four/
astearns: I think consensus is this is a good direction to take. Second question?
s/wraps/gets long and maybe wraps/
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.
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?
TabAtkins: I hadn't seen that comment, I'll have to think about that.
I am not sure, but I am intrigued
astearns: prop: we will add more terms tot he grammar to describe value ranges and such, but approach is in the air.
astearns: Objections?
proposed resolution: Extend value definition syntax to handle value ranges and possibly other syntactic restrictions, syntax TBD
RESOLVED: Extend value definition syntax to handle value ranges and possibly other syntactic restrictions, syntax TBD
I need to head out now, but I'll see you next week...

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Sep 18, 2018

FYI, I found a case of a numeric property defined to have a fixed range that isn't just non-negative or strictly positive. stroke-miterlimit was defined to accept a number (integer or decimal) that it must be equal to or greater than 1.

AKA , , or however it ends up defined syntactically!

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.

@AmeliaBR
Copy link
Contributor Author

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 (). It's a familiar syntax for pretty much anyone who is working with CSS, it is explicit about the meaning, and it has the potential to be extended in the future.

For now, we would be adding min and max attributes to all numeric, length, and other quantity data types, including combinations such as .

The min and max values would be inclusive. As Tab mentions earlier in the thread, we don't want open-ended bounds for non-integer values (e.g., to allow 0.00000000001 but not 0) because that gets into messy areas of numeric precision. For integer values, it is easy to just shift the minimum/maximum to the next allowed value (that is, to specify instead of "integer greater than 0").

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:

After each construct (declaration, style rule, at-rule) is parsed, the user agent checks it against its expected grammar. If it does not match the grammar, it’s invalid, and gets ignored by the UA, which treats it as if it wasn’t there at all.

Currently, the parser-level constraints on CSS values are defined by prose that states that certain values are invalid. E.g., the prose for font-weight currently says "Only values greater than or equal to 1, and less than or equal to 1000, are valid, and all other values are invalid."

The proposed change would encode those constraints directly in the CSS Values grammar.

@fantasai
Copy link
Collaborator

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. ;)

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Jan 29, 2019

@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:

Attribute notation

  • font-size: | |

  • font-weight: [normal | bold | ] | bolder | lighter

  • font-stretch: normal | |

  • font-style: normal | italic | oblique ?

Pros

  • familiar syntax
  • easy to read
  • extensible to other types of constraints

Cons

  • verbose

Bracket range notation

  • font-size: | |

  • font-weight: [normal | bold | ] | bolder | lighter

  • font-stretch: normal | |

  • font-style: normal | italic | oblique ?

Pros

Cons

  • similar to the syntax used for describing a number of repeated tokens
  • the single-sided bounds syntax ([0,] for zero and up) may be confusing for those not familiar with mathematical range notation

Human-readable range notation

  • font-size: | |

  • font-weight: [normal | bold | ] | bolder | lighter

  • font-stretch: normal | |

  • font-style: normal | italic | oblique ?

Pro

  • compact
  • written the way you would read it

Cons

  • The + notation can get lost among % signs or units.
  • No syntax for a maximum bound without a minimum bound (but I don't think we have any use case for this).

(Maybe replace "to" with a proper n-dash. ;)

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.

@dbaron dbaron changed the title [css-values] Define , , , etc. sub-types [css-values] Define value syntax that limits , , , etc. to ranges Feb 12, 2019
@tabatkins
Copy link
Member

  • the single-sided bounds syntax ([0,] for zero and up) may be confusing for those not familiar with mathematical range notation

Would it be troublesome to do [0,∞]? We promised to keep CSS grammar ASCII-only, but not the description of its syntax. ^_^ (And I'm okay with an ∞ showing up in Houdini code.)

@fantasai
Copy link
Collaborator

@tabatkins I thought about that as well. :) I say we go ahead and use it, but also accept the missing infinity version so that people who have trouble typing it don't have to.

@Crissov
Copy link
Contributor

Crissov commented Feb 25, 2019

Brackets and dots notation

An ellipsis made of three dots ... (not U+2026 ) could stand in for an infinity sign.

  • font-size: | |
  • font-weight: [ normal | bold | ] | bolder | lighter
  • font-stretch: normal | |
  • font-style: normal | italic | oblique ?

Dots notation

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 .. substituting to and ... for +.

  • font-size: | |
  • font-weight: [ normal | bold | ] | bolder | lighter
  • font-stretch: normal | |
  • font-style: normal | italic | oblique ?

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Adding min/max constraints, and agreed to the following:

  • RESOLVED: We will use the bracket range notation
The full IRC log of that discussion Topic: Adding min/max constraints
AmeliaBR: currently we have something like length-percent and in the prose it says negative values are invalid
github: https://github.com//issues/355#issuecomment-458324757
AmeliaBR: the idea is to get that into the actual syntax grammar
AmeliaBR: especially with various houdini APIs we're providing authors with access to the syntax
AmeliaBR: the issue is to discuss what this syntax looks like
AmeliaBR: my proposal was to look like something like sgml attributes, we're using angle brackets for data types
AmeliaBR: fantasai concern is that that can get verbose
AmeliaBR: if you go down to the second to last issue I have the different options with 4 real world examples
AmeliaBR: Any pros/cons - I've listed mine but would like to hear peopl'es feedback
fantasai: I like my proposal
fantasai: I really don't want to make things too verbose, the more the grammar has to wrap the harder it is to read
fantasai: I
fantasai: I prefer the more human readible version
https://github.com//issues/355#issuecomment-458324757
TabAtkins: shows options on screen
TabAtkins: explains the various proposals in the link above
fantasai: a min in human readible could be 0+
TabAtkins: I'm most a fan of the bracket range syntax
fantasai: if you're going to use multipliers it uses similiar syntax
TabAtkins: this is already in the syntax
TabAtkins: I agree with the idea in general
TabAtkins: I agree with AmeliaBR that with Houdini we need to provide access to this
heycam: A non syntax question
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?
TabAtkins: This shouldn't change anything this is just moving the prose into the grammar
TabAtkins: calcs are still valid and clamp to the range
heycam: if you have a property number 1-1000
heycam: and you use any calc inside that
TabAtkins: yep, that should work
astearns: does anyone have any objections to bracket notation
astearns: I would prefer to have explicit rather than empty
TabAtkins: what about writing infinity rather than the symbol
fantasai: no
iank_: are we allowing the word infinity?
iank_: I'm biased to the Javascript
TabAtkins: what about both?
iank_: I'm fine with both
AmeliaBR: that sounds the best for me
AmeliaBR: the infinity symbol is nice in a spec but not necessarily for typing in code
+1 to what AmeliaBR said
heycam: rather than brackets and commas you can use ..
TabAtkins: some languages include two dots others use three dots
gregwhitworth: I would prefer no on that
s/TabAtkins/heycam/
AmeliaBR: as fantasai noted the brackets are known in CSS in the grammar
iank_: also the ... may get confused with the destructioring in JS
TabAtkins: we will go with the bracket version and allow Infinity and the infinity symbol
TabAtkins: I would never propose the inifinty symbol for CSS itself, this is for syntax
florian: Bikeshed feature request, convert infinity word to symbol
fantasai: there is an infinity code and ampersand version

fantasai: what's the case sensitivity of the inifnity keyword?
TabAtkins: in JS it's Infinity
fantasai: as a string?
TabAtkins: it would be number [1, Infinity]
Proposal: Use the bracket range notation (from the issue), but with infinite ranges (no max/min) represented by either `Infinity` or ∞ (or negative thereof)
AmeliaBR: it's not a string it's a token within the syntax
fantasai: question, is our sytax types case sensitive
TabAtkins: the Houdini syntax cares
fantasai: yeah we're consistent in our specs but I was curious
astearns: any objections to the proposal
`syntax: "big | BIGGER"` in registerProperty() is already case-sensitive
RESOLVED: We will use the bracket range notation

@svgeesus
Copy link
Contributor

Bikeshed needs to be updated to work wit this, apparently

@AmeliaBR
Copy link
Contributor Author

Bikeshed issue: speced/bikeshed#1441

I'll make the tracking issue for the edits once that is resolved.

@tabatkins
Copy link
Member

Bikeshed's updated, plz make tracking issues @AmeliaBR ^_^

@AmeliaBR
Copy link
Contributor Author

Darnit. I had such a good excuse for not working on this. Ok, I'll tackle that this weekend.

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented May 5, 2019

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").

@tabatkins
Copy link
Member

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 copying it to the dts defining individual grammar chunks; it's a relevant piece of information, and readers are well-served by surfacing it right at its actual point of definition.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants