Skip to content
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

[css-variables] Add User Agent properties and constant() #1817

Closed
wants to merge 1 commit into from

Conversation

grorg
Copy link
Contributor

@grorg grorg commented Sep 15, 2017

Addresses issue #1693

@grorg
Copy link
Contributor Author

grorg commented Sep 15, 2017

@tabatkins I expect you'll have a lot of comments on this. For one, do you want to use the term global variables?

Also, if you want to allow the user to set their own --global-property, then I'd appreciate help on how that should be done. I assume it should only be allowed in one place, e.g :root?

@grorg
Copy link
Contributor Author

grorg commented Sep 15, 2017

The title of the commit should be User Agent properties, not variables.

@grorg grorg changed the title [css-variables] Add User Agent variables and constant() [css-variables] Add User Agent properties and constant() Sep 15, 2017
@othermaciej
Copy link
Member

How about just using "Constants" as the name everywhere, instead of "User Agent Properties" but then the syntax is constant()? Or "User Agent Constant" if there's a need for disambiguation.

This would also imply changing static readonly CSSUserAgentPropertyMap userAgentProperties; to static readonly CSSConstantMap constants;, which actually seems pretty reasonable.

@tabatkins
Copy link
Member

  1. Any discussion of "properties" here is misplaced; there's no properties involved at all. This is just a new CSS function, with similar substitution behavior to var(). Call them "constants" or "global variables".

  2. Do we want to use the exact same substitution behavior as variables? Variables have to be delayed until computed-value time, because they depend on inheritance. Global variables don't - there's nothing stopping us from making their substitution happen at parse-time, giving us all the normal grammar interactions (knocking out a declaration at parse time so it falls back to a previous declaration, etc). It does mean a change in a variable effectively

  3. If we want to allow people to set these values in stylesheets (I think we do), the right avenue is with an at-rule: @global <custom-ident> <declaration-value>;. If we expose this in the JS API, we'll need to keep track of which names are managed via CSS, so that when you mutate it via JS it mutates the CSSOM as well. I presume that if you set if via JS, then add a CSS rule, the CSS would win?

@tabatkins
Copy link
Member

3a) Alternately, make the JS API hang off of individual stylesheets, and have it be just a shorthand for adding/removing/mutating the rules directly. Then precedence is automatic - you're just adding a rule to a given stylesheet, and the standard "later stylesheets win" rule comes into effect. This is less convenient for authors, tho - you need to figure out which stylesheet a given constant is coming from if you want to manipulate it.

@othermaciej
Copy link
Member

  1. If we want to allow people to set these values in stylesheets (I think we do), the right avenue is with an at-rule: @global ;.

How would this work for UA predefined constants? Would they be expected to have an @global rule in a stylesheet at UA precedence level, which gets updated if the value changes?

I'm asking because from our perspective, UA predefined constants are the main kind we care about, and author-defined constants are at most a tangential side benefit.

Also, I really think this concept should have a single name in syntax. Either @global+global() or @constant+constant(). @global defining the value read by constant() seems needlessly inconsistent.

@upsuper
Copy link
Member

upsuper commented Sep 17, 2017

there's nothing stopping us from making their substitution happen at parse-time, giving us all the normal grammar interactions (knocking out a declaration at parse time so it falls back to a previous declaration, etc). It does mean a change in a variable effectively

There is. Couldn't global variables / constants change after page open? e.g. in case of iPhone X, what would happen if user rotates the phone or split the screen? If we substitute them during parsing, we would never be able to change it dynamically.

@tabatkins
Copy link
Member

It would require a reparse, yes.


How would this work for UA predefined constants? Would they be expected to have an @global rule in a stylesheet at UA precedence level, which gets updated if the value changes?

The UA stylesheet is unobservable, so this doesn't matter. The only observable part would be the JS API, which would I suppose have readonly entries in the map that could be listened to for changes.

Also, I really think this concept should have a single name in syntax. Either @global+global() or @constant+constant(). @global defining the value read by constant() seems needlessly inconsistent.

Oh, yes, certainly. All the discussion of "global variables" just led my fingers to type @global; whatever name we choose will definitely be used consistently between the definition and use.

@othermaciej
Copy link
Member

Is the map global rather than per-stylesheet? How are read-only entires represented?

@tabatkins
Copy link
Member

Is the map global rather than per-stylesheet?

Depends on how we answer my (3)! Global is easier for authors, I think, but per-stylesheet has simpler semantics.

One reasonable answer is both: we have a global map hanging off of the CSS global, which stores the UA constants, and which authors can add values to manually in JS, then there's a separate per-stylesheet map that's a convenient interface over the @global rule.

That way the actual CSSGlobalRule interface or whatever can stay simple and trivial, and the listen-for-changes API can hang on the maplike and be consistent between the different sources. This also lets us do just the JS API (all that's required for the UA-provided ones) first, without necessarily requiring the @global rule, in case that ends up problematic for some reason.

How are read-only entires represented?

The map-like just throws on attempted sets/deletes/clears for those keys.

@upsuper
Copy link
Member

upsuper commented Sep 19, 2017

It would require a reparse, yes.

Parsing is slow, and loses information, e.g. how would you reparse a declaration inserted via CSSOM?

I don't think reparse is an option here...

@tabatkins
Copy link
Member

Yeah, the more I think about this, the more I think we should just hew close to standard var() semantics. That makes it more amenable to having multi-values too.

@tabatkins
Copy link
Member

Went ahead and wrote up the feature as a separate spec instead: https://drafts.csswg.org/css-env-1/

More details back in #1693

@tabatkins tabatkins closed this Apr 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-variables-1 Current Work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants