You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal introduces labeled parameters for utilities by extending the --value() function with a [label:type] syntax. This enables more expressive utilities like bg-grid-[line:2px].
Why is this?
Currently, complex utilities often require either fragmentation (e.g., bg-grid-line-*, bg-grid-size-*) or generic arbitrary values that lack semantic meaning: text-[20px] likely refers to font-size, while text-[red] resolves to color, effectively "black box" -- while the IntelliSense plugin can resolve these values, they remain opaque in environments like GitHub code reviews (lacking semantic context).
We currently have syntax for type matching (e.g., text-[length:16px]), but it only matches the data type. If we need multiple values of the same data type, it doesn't work well.
This proposal introduces a structured way to handle multiple variables under one utility namespace, and will allow a single @utility to manage multiple configurable properties via a unified syntax:
bg-grid: applies the base utility with default styles.
bg-grid-white/10: resolves the line color via the modifier.
bg-grid-[line:2px]: matches --value([line:length]) to set the line width.
bg-grid-[size:--spacing(4)]: matches --value([size:length]) to set the grid size.
This approach avoids utility fragmentation (e.g. bg-grid-line-* and bg-grid-size-*) and improves readability.
A valid labelmust match [a-zA-Z0-9\-_].
And...how?
So, let's think about what bg-grid-[label:value] actually does.
The resolution strategy for bg-grid-[label:value] would be:
Match Label: The engine extracts the label (e.g., line from bg-grid-[line:2px]) and checks if the utility definition contains a corresponding --value([line:...]).
Match Data Type: If the label matches, it validates the value against the requested type (e.g., length).
Fallback:
With Label: If the label matches but the type does not (e.g., bg-grid-[line:red]), the declaration is invalid/ignored.
With [*:*]: The utility explicitly declares that any labeled value may be captured as-is, even if it does not satisfy a stricter typed binding. This acts as a generic label-to-label fallback -- if it's labeled, handle labeled only.
Without Label: Just as before; e.g., bg-grid-[4rem] will match the first definition of --value(length, [size:length]).
Other thoughts (Future Possibility, Not now)
Changed syntax
Building on this logic, we could potentially support multiple bindings within a single utility, such as chained syntax like bg-grid-[line:1px]-[size:20px], but it might pose implementation challenges.
Rewrite existing fragmentation utilities
For existing utilities, like bg-linear, we could take: bg-linear-[to_right] bg-linear-[from:white] bg-linear-[to:black] bg-linear-[via:transparent], or multiple bindings: bg-linear-[to:right]-[from:white]-[via:transparent]-[to:black].
Before and After
Now, we could rewrite some utilities currently in use in single utility with new way like:
This is a conceptual example to illustrate the potential use cases of this new syntax, existing utilities are sufficient :), thanks for your work!
Fallback Values
For labeled parameters, we could also support compile-time fallback values, it looks like --value([ size: length ?? 1rem ]), if the size label is present but the data type is mismatched, 1rem will be resolved (e.g., bg-grid-[line:red] can't match the data-type of --value([line: length ?? 1px]), but the declaration has a fallback value 1px, so it will resolve --bg-grid-line-width: 1px.
If the line label is not used, no value will be resolved.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
What is this?
This proposal introduces labeled parameters for utilities by extending the
--value()function with a[label:type]syntax. This enables more expressive utilities likebg-grid-[line:2px].Why is this?
Currently, complex utilities often require either fragmentation (e.g.,
bg-grid-line-*,bg-grid-size-*) or generic arbitrary values that lack semantic meaning:text-[20px]likely refers tofont-size, whiletext-[red]resolves tocolor, effectively "black box" -- while theIntelliSenseplugin can resolve these values, they remain opaque in environments like GitHub code reviews (lacking semantic context).We currently have syntax for type matching (e.g.,
text-[length:16px]), but it only matches the data type. If we need multiple values of the same data type, it doesn't work well.This proposal introduces a structured way to handle multiple variables under one utility namespace, and will allow a single
@utilityto manage multiple configurable properties via a unified syntax:
Usage:
bg-grid: applies the base utility with default styles.bg-grid-white/10: resolves the line color via the modifier.bg-grid-[line:2px]: matches--value([line:length])to set the line width.bg-grid-[size:--spacing(4)]: matches--value([size:length])to set the grid size.This approach avoids utility fragmentation (e.g.
bg-grid-line-*andbg-grid-size-*) and improves readability.And...how?
So, let's think about what
bg-grid-[label:value]actually does.The resolution strategy for
bg-grid-[label:value]would be:linefrombg-grid-[line:2px]) and checks if the utility definition contains a corresponding--value([line:...]).length).bg-grid-[line:red]), the declaration is invalid/ignored.[*:*]: The utility explicitly declares that any labeled value may be captured as-is, even if it does not satisfy a stricter typed binding. This acts as a genericlabel-to-labelfallback -- if it'slabeled, handlelabeledonly.bg-grid-[4rem]will match the first definition of--value(length, [size:length]).Other thoughts (Future Possibility, Not now)
Changed syntax
Building on this logic, we could potentially support multiple bindings within a single utility, such as chained syntax like
bg-grid-[line:1px]-[size:20px], but it might pose implementation challenges.Rewrite existing fragmentation utilities
For existing utilities, like
bg-linear, we could take:bg-linear-[to_right] bg-linear-[from:white] bg-linear-[to:black] bg-linear-[via:transparent], or multiple bindings:bg-linear-[to:right]-[from:white]-[via:transparent]-[to:black].Before and After
Now, we could rewrite some utilities currently in use in single utility with new way like:
bg-linear:bg-linear-x/from-x/to-x:rewrite to
bg-linear-[x]/bg-linear-[from:color]/bg-linear-[from:percentage]/bg-linear-[to:color]/bg-linear-[to:percentage]:Fallback Values
For labeled parameters, we could also support compile-time fallback values, it looks like
--value([ size: length ?? 1rem ]), if thesizelabel is present but the data type is mismatched,1remwill be resolved (e.g.,bg-grid-[line:red]can't match the data-type of--value([line: length ?? 1px]), but the declaration has a fallback value1px, so it will resolve--bg-grid-line-width: 1px.How does this sound? :D
Beta Was this translation helpful? Give feedback.
All reactions