w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.38k stars 643 forks source link

[css-properties-values-api] enhance `@property` with `scope` for `source`/`local` to determine the scope of nested custom property values #10178

Open brandonmcconnell opened 3 months ago

brandonmcconnell commented 3 months ago

The Problem / TL;DR

It'd be great to have a way to opt into granular control over the custom property values nested in the definition of other custom properties. This way, if I have one custom property I'm using, --result, and --result is comprised of some combination of several other custom properties, it would be very helpful to be able to change the value of one of those in the current scope and have that flow into the custom properties "derived" from it in that same scope.

I have encountered this myself a few times and needed a break-glass solution, but the only one was to completely redefine the outer custom property again to "re-jigger" its updated value.

Real-world examples of the issue

I propose we create a way to opt into such functionality for custom properties within the @propeprty rule.

Abstract

This proposal presents a new scope descriptor to enhance CSS custom property scoping capabilities incorporated within the @property rule. This attribute facilitates a more flexible handling of CSS custom properties. It allows fine-grained control on how nested values within a CSS variable can be read: from the source (default and current behavior) or the current local scope. This choice and difference would strongly influence the modularity of a given variable.

1. Introduction

Maintaining the structure and comprehension of styling within web applications can pose challenges. The ability to control where a CSS custom property looks to for nested values greatly enhances the flexibility and power of CSS variables. The scope descriptor for the @property rule is proposed to extend the control for developers over custom properties within their stylesheets.

2. @property Rule Enhancement for Scope Control

2.1 Declaring Scope

@property --shadow {
  scope: source | local;
  syntax: '<color>';
  inherits: true;
  initial-value: 0 4px 8px var(--shadow-color, rgb(0 0 0 / .5));
}

2.2 Scope Attributes

Source (Default): The property reads nested values in its original defined scope.

@property --shadow {
  scope: source;
}

Local: The property reads nested values in its current local scope.

@property --shadow {
  scope: local;
}

3. Use Cases

The improved level of control, such as enabling child scopes to redefine nested values that will 'locally' cascade down into other dependent variables provide several benefits:

4. Gotchas/Considerations

4.1 Compatibility

Consideration must be given to how this new feature will be introduced seamlessly without breaking the existing designs. Also, plan a graceful degradation strategy for browsers that don't support this feature yet.

4.2 Clarity over Priority or Precedence

Clear rules or expectations need to be established when both local and source variables are available. The precedence rules should be intuitive for developers to accurately predict which value will be applied.

5. Conclusion

The introduction of the scope descriptor in the @property rule augments the expressiveness and power of CSS, enabling developers to leverage more control over their CSS variables by allowing fine-grained control over the scope of variable values, thereby fostering an increasingly modular approach to styling.

yisibl commented 3 months ago

I think it would be better in combination with @scope.

brandonmcconnell commented 3 months ago

@yisibl Would you mind demonstrating what you're envisioning?

yisibl commented 3 months ago
@scope [(<scope-start>)]? [to (<scope-end>)]? {
  @property --foo {}
} 
brandonmcconnell commented 3 months ago

@yisibl Ah but the primary use case here is for custom properties with nested custom properties in their values to be able to reactively update when those nested properties are updated further down in the cascade/CSSOM.

Using at-property within at-scope might need to be a separate proposal, unless I'm missing the direct correlation. 🙂

bramus commented 3 months ago

Using at-property within at-scope might need to be a separate proposal, unless I'm missing the direct correlation. 🙂

That is a different issue indeed. Some time ago I have filed https://github.com/w3c/csswg-drafts/issues/9077 for what @yisibl is asking, but turns out it is not possible. See https://drafts.css-houdini.org/css-properties-values-api-1/#shadow-dom for an explanation why.