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

Use CSS as a transfer format instead of JSON. #185

Closed
romainmenke opened this issue Nov 17, 2022 · 13 comments
Closed

Use CSS as a transfer format instead of JSON. #185

romainmenke opened this issue Nov 17, 2022 · 13 comments

Comments

@romainmenke
Copy link
Contributor

romainmenke commented Nov 17, 2022

Because I can't help but wonder if JSON was picked only because it is the go-to format to communicate data between programs. I want to make sure this choice was the right one.


A lot of the work being done here in the DTCG has been done before by the CSSWG.

  • type definitions
  • property definitions
  • language syntax
  • language grammar
  • ....

With CSS we already have a way to communicate style information in a structured, machine readable manner.

There is also a very large and healthy community around it.
There are parsers and serialisers in many programming languages.

Instead of inventing something new and trying to force it to work in JSON I propose we just use CSS.

{
  "shadow-token": {
    "$type": "shadow",
    "$value": {
      "color": "#00000088",
      "offsetX": "0.5rem",
      "offsetY": "0.5rem",
      "blur": "1.5rem",
      "spread": "0rem"
    }
  }
}

could be :

/* file: brand.tokens.css */
@token shadow-token {
  box-shadow: 0.5rem 0.5rem 1.5rem #00000088;  
}

Groups can be done in multiple ways :

@token your-group {
  @token shadow-token {
    box-shadow: 0.5rem 0.5rem 1.5rem #00000088;  
  }

  /* more tokens */
}

/* override a single token from a group */
@token your-group.shadow-token {
  box-shadow: 0.5rem 0.5rem 1.5rem pink;
}

Custom properties already exist :

@token shadow-token {
  box-shadow: 0.5rem 0.5rem 1.5rem #00000088;  
  --something-specific-to-my-tool: "hello";
}

Starting out with support for everything in the CSS specification will be impossible.
But a small subset can be defined and can be expanded over time.

It allows the DTCG to focus on these aspects :

  • definition of the custom @token at rule
  • definition of the adopted subset of the CSS specification
@lukasoppermann
Copy link
Contributor

But this means every tool that wants to transform tokens needs to write parsing logic. Also output may not be css but xml for android or other files e.g. for swift. This means css properties need to be parsed into a json like shape to re-structure to other languages.

@romainmenke
Copy link
Contributor Author

romainmenke commented Nov 17, 2022

But this means every tool that wants to transform tokens needs to write parsing logic.

For CSS as a language :
Parsers, serialisers exist for most languages.
More can be created.

For the specific schema :
Same is true for a JSON based schema.

Also output may not be css but xml for android or other files e.g. for swift.

The same is true for JSON.

This means css properties need to be parsed into a json like shape to re-structure to other languages.

The same is also true for JSON.
Only JavaScript has a special relationship with JSON.

All other programming languages need to parse to their equivalent.


I definitely do not mean that CSS is a more common data format.
It is not. Using CSS for this would be unusual today.

But the CSSWG has done so much work to create ways to record visual/style information in a file. Not building on top of that seems like a waste.

Declaring design tokens is something that can be done in CSS and I think it is worth further exploring the benefits of such an approach.

@lukasoppermann
Copy link
Contributor

The same is also true for JSON.
Only JavaScript has a special relationship with JSON.

All other programming languages need to parse to their equivalent.

What I meant to say is that JSON is a standard that has ready to use parsers in nearly all languages.

For CSS as a language :
Parsers, serialisers exist for most languages.

I was / am not aware of that. So there are css to property parsers? One would need to turn 0.5rem 0.5rem 1.5rem pink into individual properties to use in tools that don't have a css like syntax.

@romainmenke
Copy link
Contributor Author

romainmenke commented Nov 17, 2022

There is definitely a tradeoff here. They are both better in different aspects.

Using JSON as a format has benefits because the format is simpler and has wide support for parsers/serialisers.

CSS would be easier because the specification work for all the needed value types has already been done.

Working together with the CSS tooling community would also have benefits for the design token tooling community.


So there are css to property parsers? One would need to turn 0.5rem 0.5rem 1.5rem pink into individual properties to use in tools that don't have a css like syntax.

How each value needs to be parsed is well defined in CSS.
These definitions have been tested through and through by CSS authors and multiple browser vendors.

https://drafts.css-houdini.org/css-typed-om/#stylevalue-objects

Converting CSSOM value strings into meaningfully typed JavaScript representations and back can incur a significant performance overhead. This specification exposes CSS values as typed JavaScript objects, to make manipulating them both easier and more performant.

The interfaces described in CSS Typed OM can be interesting.

These allow you to create a tool with roughly this outline :

  • parse following the CSS parser definitions
  • internal representation is blackbox and any tool can do what they want
  • expose the internal objects through the same interfaces as defined by Typed OM. This can be useful for plugin systems.

@PavelLaptev
Copy link
Contributor

PavelLaptev commented Nov 17, 2022

@romainmenke CSS like format is no good to declare things like design tokens. There are several reasons:

  1. It will take time to figure declarations inside like arrays, strings numbers all these types how we show them? CSSOM doesn't have these basic types that all programming languages have.
  2. I agreed with @lukasoppermann JSON already implemented format. Actually, you don't need to parse JSON inside SWIFT environment, e.g. packages like Style Dictionary or others will do that using JS. And JS has the native JSON support.
  3. We are not inventing a new format or rules, but mixing CSS syntax with something else, yes. JSON has its rules, and structured better then CSS — simpler.
  4. Unfortunately, we can't fully use all props and options we have in CSS because it's not possible to transpile them for other platforms, like animation props. We will need to write them not like in CSS.
  5. The goal is not support the web, but create something that could be transpiled to other platforms as well.

Easy implementation and usage is the key here.

@romainmenke
Copy link
Contributor Author

romainmenke commented Nov 17, 2022

  1. It will take time to figure declarations inside like arrays, strings numbers all these types how we show them? CSSOM doesn't have these basic types that all programming languages have.

Can you give concrete examples of something that isn't possible to express in CSS syntax?
Lists of values can easily be expressed in CSS with a comma separated list : a, b, c, d, ...

  1. Actually, you don't need to parse JSON inside SWIFT environment, e.g. packages like Style Dictionary or others will do that using JS. And JS has the native JSON support.

If the argument is that an intermediary tool is doing the heavy lifting then the same would be true when using CSS as a file format. An intermediary tool around JSON could be replaced by an intermediary tool around CSS.

  1. We are not inventing a new format or rules, but mixing CSS syntax with something else, yes. JSON has its rules, and structured better then CSS — simpler.

I don't follow this statement and don't understand what you mean with this.
Can you elaborate?

  1. Unfortunately, we can't fully use all props and options we have in CSS because it's not possible to transpile them for other platforms, like animation props. We will need to write them not like in CSS.

I don't expect design tokens to adopt the whole of CSS.
I made it clear that the DTCG would need to define the parts of the CSS specification it intends to adopt.

  1. The goal is not support the web, but create something that could be transpiled to other platforms as well.

The web does not benefit from this approach.
Using the CSS syntax and value definitions does not mean that the file is usable as CSS for a web project.

We would only use the CSS syntax and value definitions to get a head start for a transfer file format.


CSS at it's core is just a data format to communicate visual/style information to another program.

That it has been used mostly in browsers should not be a reason not to use it for other things.

@equinusocio
Copy link

equinusocio commented Nov 23, 2022

One of the core principles of design tokens is that they are platform agnostic because they MUST be usable in differnt implementation/design. A single design tokens must support other platforms too, that's why they have to be raw data and then transformed for the supported platforms.

Eg.

{
  "space-8": {
    "$type": "space",
    "$value": 8
  }
}

On iOS may become 8pt and on web may be transformed into 1rem or 8px.

Since CSS is already a domain-specific (or platform-specific), and so is one output language, more precisely the one for web-based implementations (but there are many supported formats on web), it cannot be the initial format for tokens then, the same way design tokens unlikey hold css-specific values like rem, % etc...

@romainmenke
Copy link
Contributor Author

romainmenke commented Nov 23, 2022

I think you misunderstood what I meant with this proposal :)

I do not mean to encode design tokens as CSS that would work in a browser.
This would never work because there is no document tree to match things against.

I meant to use CSS as a basis for a storage format.

/* file: brand.tokens.css */
@token shadow-token {
  box-shadow: 8 8 24 #00000088;  
}

This is syntactically correct CSS and uses existing specifications for parsing, serializing.
It also uses existing specifications for values and properties.

It however does nothing in a browser.
If you want to use this token in CSS for a website you would need to convert it just like you would need to for iOS or any other platform.


In a way this is a counter point to :

There seems to be resistance to making the specification lean and easy to consume in software.

This proposal embraces the reasons behind that :

  • easy to read/write for humans
  • very forgiving so that anyone can experiment with custom things not (yet) in the specification
  • reducing the surface the specification needs to define

@romainmenke
Copy link
Contributor Author

I know this change will never happen.
But I still think it is valuable to not always pick JSON as the one and only data format.

Many issues that are being raised here are the result of inventing yet another way to encode style/visual data. This work was already done for CSS by the CSSWG.

CSS isn't widely seen as something that can be used outside the browser, but it can and doing so can have benefits.

@equinusocio
Copy link

equinusocio commented Nov 23, 2022

It would make sense, i agree, but i see this as "evolution" of a standard. It may be an alternative syntax (like json vs. yaml) but at current state i think we should focus on having one standard at least.

@romainmenke
Copy link
Contributor Author

we should focus on having one standard at least

Absolutely :)

@kevinmpowell
Copy link
Contributor

We've reviewed this issue. There's some good points here, but we're sticking with JSON as the Design Tokens format for now.

@romainmenke
Copy link
Contributor Author

romainmenke commented Dec 5, 2022

Thank you for reading and evaluating this idea :)

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

5 participants