Skip to content

[proposal] New CSS conditional rule to detect registration events #882

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

Open
AmeliaBR opened this issue May 3, 2019 · 5 comments
Open

[proposal] New CSS conditional rule to detect registration events #882

AmeliaBR opened this issue May 3, 2019 · 5 comments

Comments

@AmeliaBR
Copy link

AmeliaBR commented May 3, 2019

Rationale

Currently, using custom properties or worklets short-circuits many of CSS's normal fallback mechanisms. The JS registration happens asynchronously compared to CSS parsing, so at parse time there is no way to know what will or won't be valid after registration. The chosen approach is to accept all possible custom things as valid at parse time, and invalidate them at computed-value time. But that means that the options for invalidation don't include falling back to other declarations for the same property.

For non-registered custom properties, authors can use an @supports test coupled with their own knowledge of their custom properties. For example, to test that a var() function will work in a given property, they can construct a supports test that uses a sample literal value instead:

@supports (text-decoration: red) {
  :link { text-decoration: var(--accent-color) underline; }
}

But that doesn't address cases where you might want different fallback values depending on whether or not relevant Houdini code has successfully run. For example, maybe you want to change an animation if your custom property won't be able to interpolate in a type-aware manner. Or you want a specific fallback display value if a Layout Worklet fails to load.

Currently, the only ways to handle these cases are to add or remove style rules from JS itself, or to use JS to set a document-level class after the registrations are complete (and use that class in all your selectors).

Proposal: @registered conditional rule

@registered would be a new conditional group rule similar to @media and @supports. It would limit the application of the child rules depending on whether or not a given registration event has been processed:

Other syntaxes could be added as necessary, e.g., for custom functions (as proposed in #857), or if a declarative version of Animation Worklets is ever defined.

Just like the existing conditional rules, you could combine multiple tests with parentheses and Boolean operators.

Note: the likely place for spec'ing this rule would be CSS Conditional Rules Level 4. But since the details and use cases are all Houdini-related, I figured it made sense to open the discussion here.

@andruud
Copy link
Member

andruud commented May 6, 2019

Note that "registeredness" of custom properties is currently a computed-value-time thing, this would violate that, I think.

Registering a custom property must not affect the cascade in any way.

@AmeliaBR
Copy link
Author

AmeliaBR commented May 6, 2019

Yes, this would change the final cascaded values after registration. Which is kind of the point.

As I understand, the reason for that restriction is to avoid a full reparse after registration. This proposal is trying to address the authoring limitations that creates, while still isolating the impact in a manner that can be optimized. With this rule, registering a property would have a similar effect on the cascade as triggering a media query (e.g., as happens when changing the window size or switching from landscape to portrait mode).

Maybe this is the wrong approach, but I hope we're not writing off the possibility of ever being able to do anything smart about setting values conditional on a registration going through or not.

@andruud
Copy link
Member

andruud commented May 6, 2019

@andruud backs up slowly, as if confronted with a scary bear.

My point wasn't "your feature sucks", it was that we need to think through what the implications are, and "registering a custom property must not affect the cascade in any way" is one of the things we need to think about.

🙂

@AmeliaBR
Copy link
Author

AmeliaBR commented May 6, 2019

And I didn't mean to sound so defensive. 🐻

But yes, there is no way to solve these use-cases (smarter fallbacks for custom CSS features) without changing that statement. So yes, we need to think about it, but in a way that focuses on the reasons behind it.

@tabatkins
Copy link
Member

So the "must not affect the cascade" thing was to ensure that we didn't need to either:

  • do a global re-parse of all stylesheets every time a new thing was registered, or
  • expensively hold onto all custom stuff (along with side information like specificity) and re-evaluate just them every time a new thing was registered

I think a whole block which is explicitly declared to depend on registration doesn't trigger these concerns. It's equivalent to some JS inserting a stylesheet alongside registering a property.

Notably, this does not change the fallback behavior; registered props still are assumed valid until computed-value time, etc. This just allows you to supply different styles if the registration succeeds or not, which seems useful.

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

3 participants