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
base: master
from

Conversation

Projects
None yet
5 participants
@grorg
Contributor

grorg commented Sep 15, 2017

Addresses issue #1693

@grorg

This comment has been minimized.

Show comment
Hide comment
@grorg

grorg Sep 15, 2017

Contributor

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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@grorg

grorg Sep 15, 2017

Contributor

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

Contributor

grorg commented Sep 15, 2017

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

@grorg grorg changed the title from [css-variables] Add User Agent variables and constant() to [css-variables] Add User Agent properties and constant() Sep 15, 2017

@othermaciej

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Sep 15, 2017

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.

Member

othermaciej commented Sep 15, 2017

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

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Sep 15, 2017

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?

Member

tabatkins commented Sep 15, 2017

  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

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Sep 15, 2017

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.

Member

tabatkins commented Sep 15, 2017

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

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Sep 15, 2017

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.

Member

othermaciej commented Sep 15, 2017

  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

This comment has been minimized.

Show comment
Hide comment
@upsuper

upsuper Sep 17, 2017

Member

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.

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

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Sep 19, 2017

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.

Member

tabatkins commented Sep 19, 2017

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

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Sep 19, 2017

Member

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

Member

othermaciej commented Sep 19, 2017

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

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Sep 19, 2017

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.

Member

tabatkins commented Sep 19, 2017

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

This comment has been minimized.

Show comment
Hide comment
@upsuper

upsuper Sep 19, 2017

Member

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

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

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Sep 20, 2017

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.

Member

tabatkins commented Sep 20, 2017

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

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Apr 27, 2018

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

Member

tabatkins commented Apr 27, 2018

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