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

Support for design tokens #193

Closed
romainmenke opened this issue Jun 2, 2022 · 10 comments
Closed

Support for design tokens #193

romainmenke opened this issue Jun 2, 2022 · 10 comments

Comments

@romainmenke
Copy link

Hi!

After releasing https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-design-tokens#readme I was curious to hear your feedback on this and gauge your interest of implementing something similar in @parcel/css.

Our main concern with existing tools around design tokens is that these take away too much control and freedom from stylesheet authors. (creating an accessible website is impossible for example)

Converging on a single way to expose design tokens in CSS source code will help stylesheet authors switch tooling or even use multiple tools side by side.

This will also make it more worthwhile for other tools (editors, linters, ...) to support this.

Any feedback or insights would be greatly appreciated :)

@devongovett
Copy link
Member

Curious why you need a custom syntax for this rather than using var()?

@romainmenke
Copy link
Author

With generated custom props files you introduce multiple issues.

  1. The name/id format used in design tokens is not compatible with CSS by design. Most tools just throw warnings when their lossy conversion results in naming conflicts. This does not create a smooth developer experience when trying to use tokens.

  2. It is impossible to know which tokens are actually used in a project if everything is generated as custom props. This causes bloat.

  3. The end result will most likely have accessibility issues. This is a tradeoff I am not willing to make. I do not want to sacrifice accessibility to consume design tokens.

The most basic example of this is px vs. rem. Design tools have just a single boolean switch : "export as rem" vs "export as px". But you need both units to create accessible websites.

Overal generated files (with custom props / var()) take away too much control from developers.
Control which is needed to produce high quality and accessible products.

@romainmenke
Copy link
Author

romainmenke commented Jun 7, 2022

Another issue are the proposed composite types : https://design-tokens.github.io/community-group/format/#composite-types

With style-dictionary there is a fairly good mapping between CSS properties and tokens.

But composite types (part of the proposed spec) are less like an "atom" and more like "molecules".
I personally do not think these are a good idea (in the current form) but haven't had much success in expressing my concerns here.

These do not always map to a single CSS property and will need "destructuring" so that sub values can be assigned to the corresponding CSS properties.

This can only be done with custom syntax (as far as I know).

@jamiebuilds
Copy link
Member

Seems like this would be better integrated as a Parcel plugin for Style Dictionary that produces a CSS "virtual file" with all of the CSS variables.

@romainmenke
Copy link
Author

romainmenke commented Jun 8, 2022

Seems like this would be better integrated as a Parcel plugin for Style Dictionary that produces a CSS "virtual file" with all of the CSS variables.

I would really like this to work but as far as I know it is impossible to convert design tokens to CSS variables and have these things :

  • developers can chose both rem and px units when consuming a single token (critical for a11y)
  • there are no naming conflicts when converting token names to CSS variables
  • there will never be a composite type that needs to be split over two CSS properties

These issues are self inflicted and could be resolved in the draft design tokens specification.

Overal my concern is that design token translation tools make the simple cases a little bit easier while also making it harder (or impossible) to solve complex issues. (easier to consume a design constant, harder to create an accessible website)

The syntax used in the PostCSS plugin aims to make it equally easy/hard.

@devongovett
Copy link
Member

It is impossible to know which tokens are actually used in a project if everything is generated as custom props

We recently added support for locally scoped CSS variables in CSS modules, which solves this problem. Variables aren't global, and are explicitly referenced between files so we can automatically exclude unused vars. I believe webpack is also planning to implement the same syntax, so it should eventually be interoperable between tools as well. https://parceljs.org/blog/v2-6-0/#locally-scoped-variables-in-css-modules

The px vs rem issue is interesting, but IMO these should be separate tokens anyway as they represent semantically different things. Some things you want to scale with the font size, and others not, but these shouldn't be the same token because they don't represent the same value.

Overall, I've always kinda wondered whether a JSON-based token system is even necessary to begin with. To me, it seems that defining tokens as JSON rather than using CSS syntax is worse is most ways. It's an unnecessary level of abstraction that makes it less clear how to use the defined variables (how do they map to CSS variable names?), and makes it harder to author and work with CSS tooling (e.g. syntax highlighting, linting, hot reloading, etc.). The claimed benefit of being "cross platform" could also be solved using CSS as the authoring format rather than JSON, which makes more sense because CSS is a language specifically designed for this exact task, whereas JSON is not. Maybe I am missing something here.

@romainmenke
Copy link
Author

Overall, I've always kinda wondered whether a JSON-based token system is even necessary to begin with. To me, it seems that defining tokens as JSON rather than using CSS syntax is worse is most ways. It's an unnecessary level of abstraction that makes it less clear how to use the defined variables (how do they map to CSS variable names?), and makes it harder to author and work with CSS tooling (e.g. syntax highlighting, linting, hot reloading, etc.). The claimed benefit of being "cross platform" could also be solved using CSS as the authoring format rather than JSON, which makes more sense because CSS is a language specifically designed for this exact task, whereas JSON is not. Maybe I am missing something here.

Hehe, this is literally what I've been wondering as well.
I also do not understand why the entire effort to create a format for style information is restarted in JSON.

If this were a raw format that didn't require parsing I might understand that.
But as it is proposed today it would be filled with micro syntax. Some of which derived from CSS but not all.

The px vs rem issue is interesting, but IMO these should be separate tokens anyway as they represent semantically different things

True but this is not how it is implemented in design tools today :/
This would require designers to have the tools and knowledge to pick and apply px/rem correctly.


Overal I feel that the draft for design tokens does not get enough feedback from people writing CSS or creating tools for CSS.


Thank you for these insights!

@devongovett
Copy link
Member

I think this could be solved by the custom transform API I'm working on (#363). I implemented a very basic version of it in the tests.

visitor: {
Function: {
'design-token'(fn) {
if (fn.arguments.length === 1 && fn.arguments[0].type === 'token' && fn.arguments[0].value.type === 'string') {
return tokens[fn.arguments[0].value.value];
}
}
}
}

@romainmenke
Copy link
Author

Awesome!
Then I think this issue can be closed?

If someone wants this feature in lightningcss they can make a plugin for it 🎉

@devongovett
Copy link
Member

The custom transform API is now released! See https://lightningcss.dev/transforms.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants