Re: [community-group] [RFC] Format specification (#1)

Hi again. What a lot of great thoughts!
Let me explain better my proposal of using a CSS-like syntax.

## Why a CSS-like syntax?

I'm agree with many of you that design tokens are key-value pairs, with nested groups, so they could be represented with JSON. Example:

```json
{
  "typography": {
    "font-family": "Arial",
    "font-size": "24px"
  }
}
```

But the problems I see with JSON are:

- It's not easily editable by humans
- It doesn't allow to add comments or extra data, so to add support for more than simply key-value pairs, we'd need to create and standardize a more complex data structure like following:

```json
{
  "typography": {
    "comments": [
      "First comment",
      "Second comment"
    ],
    "value": {
      "font-family": {"value": "Arial"},
      "font-size": {"value": "24px"}
    }
  }
}
```

Other option is using YAML, a more human format, that allows to add comments:

```yaml
# This is a comment
# Another comment
typography:
  font-family: Arial
  font-size: 24px
```

That's a good option but has some drawbacks:

- Yaml cannot be minified because depends heavily on spaces, so it's not a good format to return data from an API, for example.
- It's a fragile format. A bad indentation breaks the file. I know people that hate Yaml because this.

Other drawback of JSON and YAML is not about the structure of the tokens but how express the values. Colors are one of the most clear examples. Sketch, Figma, CSS, Swift, Java... all have different methods to represent colors. So we need a standard way to represent them as tokens. And the same for other values like dimmensions, gradients, different units, animations, etc. 

CSS is a language that have support and documentation for all these stuff and have additional features:

- The syntax is simple and robust. There are no problems with indentations like YAML or quotes and trailing commas like JSON.
- It's flexible: allows comments, the format can be minified and loaded remotely.
- Includes additional features in form of at-rules, so you can add some kind of logic in the tokens file, for example:
  - Import extra dependecies using `@import`
  - Define conditions using `@media`
  - There are some additional features not standard yet, but that could be included someday, like [`@extend`](http://tabatkins.github.io/specs/css-extend-rule/) or [`@when / @else` ](https://tabatkins.github.io/specs/css-when-else/)
  - Or even new at-rules that we can create to solve specific problems with design tokens

@c1rrus says:

> My (possibly incorrect) interpretation of @oscarotero's original proposal was an alternative, CSS-inspired syntax for expressing same kind of design token input data. So, for instance, a future Style-dictionary-like tool might read in such files instead of JSON.

Yes, exactly! My proposal is not about using the CSS format as is to store tokens, but creating a new format, inspired in CSS and taking advantage of all its standards. So when a tool import this new format, it nows how the colors, units, fonts, etc are expresed and how transform these values to use them in other platform (CSS, SASS, LESS, iOS, Android, CSS-in-JS, etc).

@c1rrus also says:

> Is the nesting...

> * a short-hand for declaring some tokens whose names share common prefixes? I.e. it's equivalent to something like typography.main.font-family: $font-families.display; typography.main.font-size: $sizes.medium; ...
> * or, is this like a bunch of CSS declarations - i.e. you're assining the value of the $font-families.display token to the font-family property. If so, what is typography main selecting?
> * something else entirely ;-)

In my opinion, is the first case, illustrated with this example:

```css
typography {
    main {
        font-size: $sizes.medium
   }
}

/* It's equivalent to: */
typography {
    main.font-size: $sizes.medium;
}

/* And to: */
typography.main.font-size: $sizes.medium;
```

Anyway, this is just sugar syntax, so I don't have a strong opinion about adding support for this or not. Just want to illustrate that in this format there are no selectors. Only key-value pairs.


## Uniqueness

In my company, we have a white-label product, so we have basic styles and them multiple themes, created by overriding the tokens (mainly colors and fonts). So this new format should allow to override these values at any point, in the same way that CSS.

## Aliasing

From a designer perspective, aliasing is a must. Design systems are recursive, and one clear example is the atomic design system, in which a value (atom) is used to generate a more big value (molecula) and this value will generate a even bigger value (organism). So we need a way to create aliases between values, in order to avoid repetition.

## Practical example

### For designers

I imagine design sofware like Sketch, Figma or Adobe XD with support for this new format, so you could have a panel to import and edit tokens in order to use them later in the elements. Maybe a simple text editor where you could include some `@import` to load the common tokens of your design system, override other values, leave comments, etc. These design tokens could be used to apply colors, styles, border width, fonts, etc to the elements of the document (for example, a button, or a text).

An example using Sketch:

![tokens](https://user-images.githubusercontent.com/377873/88318216-b2c01d00-cd1a-11ea-87d4-ad566ca7b810.jpg)

### For developers

The developers could use any tool (like Style-dictionary, Diez etc) to load these tokens and convert them to values that can be used in each platform (css, swift, android, etc). In CSS, the tokens could be converted to css variables, but also there could be a postcss plugin to use them directly, for example:

```css
.button {
    background-color: $colors.primary;
}
```

Other example: In my company, we are using [mjml](https://mjml.io/) to create emails, and you must assign style values as attributes (see, for example, [the button component](https://mjml.io/documentation/#mj-button)). We could use the tokens here too:

```html
<mj-button background-color="$colors.primary">Click me</mj-button>
```

## Typing

CSS has not typings and in most of cases it's not necessary. If we use the CSS way to represent values, we can detect that `#333` is a color, `23px` is a dimmension unit, `45deg` is a degree unit, `200ms` is time unit and even `lineal-gradient($colors.primary, $colors.secondary)` is a gradient. So, tokens consumers could load all these values and detect its type. I imagine, for example, Sketch or Figma could show all the tokens containing colors in the color palette, gradients tokens in the gradients palette... automatically.

But typing could be a nice feature anyway. I've proposed a simple syntax here: https://github.com/design-tokens/community-group/issues/1#issuecomment-660286004 but open to other proposals.

-- 
GitHub Notification of comment by oscarotero
Please view or discuss this issue at https://github.com/design-tokens/community-group/issues/1#issuecomment-663158695 using your GitHub account

Received on Thursday, 23 July 2020 18:18:54 UTC