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

Themes/Schemes vs. Design Tokens #187

Open
equinusocio opened this issue Nov 23, 2022 · 7 comments
Open

Themes/Schemes vs. Design Tokens #187

equinusocio opened this issue Nov 23, 2022 · 7 comments

Comments

@equinusocio
Copy link

equinusocio commented Nov 23, 2022

After some years of working with DS and design tokens, I'm happy to see something "official" around this topic, but I would like to highlight the concepts of design tokens vs. themes.

Design tokens vs. themes. Semantic vs. non-semantic.

We know design tokens have specific core values:

  • Design tokens don't change across implementations. They are constants.
  • Design tokens are platform-agnostic raw data; you must transform them into specific formats used by destination platforms, like the web, iOS, and Android.
  • Design tokens are non-semantic. They hold an absolute value.
  • Design tokens are the single source of truth to keep consistency across the system and platforms

But what we have right now is a need for clarification about what a design token can do in real-life usage. I see the idea that design tokens' value can change across the system while what can change are only the keys used for themes/schemes, as shown in the official talk below.

From https://youtu.be/ssOdzxZdg58?t=833

From https://youtu.be/ssOdzxZdg58?t=833

Since design tokens never change across the system, but themes do, don't we think we can clarify what a theme is and what a design token is? Calling everything "design token" is wrong since they have different scopes and add confusion about the actual usage.

I don't know how, but adding a section in the spec about themes/schemes and clarifying examples by avoiding theme-style names for design tokens. Like --global-background isn't likely a real name for a design token; it is probably a key used inside themes instead.

Conclusion

  • Theme's values (semantic keys) may change across the system and implementation.
  • Design Tokens values are the same across every implementation (of course, i'm talking about the raw data, not the transformed platform-specific value)

Isn't calling everything "design tokens" lot confusing and far to be clear for users?

@caoimghgin
Copy link

I agree naming conventions have not reached anywhere near standardization but I'm not certain naming key/values 'design tokens' is where we misalign. Let's start with colors.

  • Definitive Color names are Purple, Grey, Lilac, or even #555555. They say what the color is, but not its intention.
  • Contextual Color names such as Color Accent, Color Text Body are best described as 'contextual' since they typically use two other color tokens to describe behavior in dark/light mode in the context of backgrounds and/or specific components.
  • Semantic Colors are primary, secondary, warning, info, danger, neutral, etc. and describe design intention regardless of the specific color.

When it comes to white-label, very valuable to abstract away from Definitive Color names. If the color is named primary it's very easy to update the green color to blue but very tedious to re-map all contextual colors from $green to $blue. I only know because I've been there, done that.

At least for colors, we have a long way to go in alignment on what the name of color actually means, its purpose, and its intention. Calling Color Text Body a Semantic name comes from CSS Semantic naming conventions, but practically it is too specific a name IMHO.

Anyway, in short, ALL ARE design tokens, but we need to work on the deeper meanings of what kind of tokens they are.

@PavelLaptev
Copy link
Contributor

PavelLaptev commented Nov 23, 2022

@equinusocio I think in terms of JSON format all values are constants, because we don't override them as variables.

const color500 = "#FF4455"
const color200 = "#FFC7CC"

let colorAccent

if (darkmode === true) {
  colorButton = color200
} else {
  colorButton = color500
}

Of course, we have aliases but it's different. In CSS variables, it will be converted like this if we have different themes.

:root {
  --color-main-500: #FF4455;
  --color-main-200: #FFC7CC;

  --color-button-lightmode: var(--color-main-500);
  --color-button-darkmode: var(--color-main-200);
}

In order to achieve overriding in CSS we need to do it manually. Of course there could be a plugin to covert themes into classes, but different companies could use different implementations or methods of working with tokens.

:root {
  --color-main-500: #FF4455;
  --color-main-200: #FFC7CC;
}

.lighttheme {
  --color-button: var(--color-main-500);
}

.darktheme {
  --color-button: var(--color-main-200);
}

but even here we don't override --color-button. It doesn't exist outside theme classes. But it's possible if we declare --color-button in root.

:root {
  --color-main-500: #FF4455;
  --color-main-200: #FFC7CC;

  --color-button: var(--color-main-500);
}

.darktheme {
  --color-button: var(--color-main-200);
}

@equinusocio
Copy link
Author

equinusocio commented Nov 23, 2022

Speaking about design tokens core principles, aliases (aka themes) don't share the same principles like being the source of truth across the system.

If product A sets color-500: #ff00ff and product B sets color-500: #00ff00, then that principle is broken; tokens are not consistent anymore, and they become unpredictable across the system.

That’s why aliases/themes are useful; their value can change across the system and implementation: Product A can use a theme with link-color: {color.500}., while product B can use another theme with the same key but different value, like link-color: {color.200}. And avoid breaking that token principle.

So, using the same name for different things seems confusing. We say design tokens are the single source of truth, but we show “tokens” changing values across implementations.

@ilikescience
Copy link

@equinusocio I want to acknowledge that while the principles of design tokens you shared are good principles, they aren't in the current definition of this specification, so it's hard to be precise about whether they are or are not correctly applied.

Like @PavelLaptev says, we take advantage of the features of JSON to prevent tokens from having ambiguous values. The following is not valid JSON, and therefore it's not a valid token file:

{
  "color-500": {
    "$value": "#ff00ff",
    "$type": "color"
  },
  // later in the file ...
  "color-500": {
    "$value": "#00ff00",
    "$type": "color"
  }
}

This isn't valid JSON, either:

{
  "link-color": {
    "$value": "{color.500}"
  },
  // later in the file ...
  "link-color": {
    "$value": "{color.200}"
  }
}

So within an implementation there shouldn't be any issue. Of course there's no perfect guarantee, and the more complex a system is the more likely there will be bugs. Actually. your example lays out a good principle of best practice to avoid bugs: always use aliases, don't try to modify the underlying value.

@equinusocio
Copy link
Author

I want to acknowledge that while the principles of design tokens you shared are good principles, they aren't in the current definition of this specification, so it's hard to be precise about whether they are or are not correctly applied.

Isn't something useful and foundamental for the spec that you may consider to add?

Like @PavelLaptev says, we take advantage of the features of JSON to prevent tokens from having ambiguous values.

yeah, i see now that what technically comes after, like tokens transformation, is up to consumers and it's just a matter of best practices. I still find hard to consider everything as design token cause in this example:

{
  "link-color": {
    "$value": "{color.500}"
  },
  // later in the file ...
  "link-color": {
    "$value": "{color.200}"
  }
}

link-color violates the first principle if considered as token, but it doesn't if is considered as theme-key.

@ilikescience
Copy link

link-color violates the first principle if considered as token, but it doesn't if is considered as theme-key.

Just to be super clear, the link-color example was meant as a demonstration of an invalid token definition. A parser ('translation tool' in the spec) should fail to process those tokens, with an error like error: duplicate key found.

@equinusocio
Copy link
Author

equinusocio commented Dec 1, 2022

Yep yep i know, i'm arguing about the transformation and "pushing" on best practices somewhere over the raimbow, but at this point it looks like something outside the spec itself.

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

No branches or pull requests

6 participants