Tiers of Sorrow
Tiers can be confusing, so let's improve them
I was having a conversation with my wife the other week. She was in the middle of a token naming exercise. And her issue was that she had a primitive token named heading-xl and was trying to figure out what the semantic token should be named that is mapped to the primitive. As it would be confusing to have a primitive token called heading-xl mapped to a semantic token also called heading-xl.
About tiers
Forgetting that scales like T-shirt sizing aren’t truly semantic, it brings up the discussion about how you can be sure what belongs in a particular tier. In case you aren’t familiar with tiers in design tokens, here’s the definition from Tokenpedia:
A group of tokens of the same type and purpose, usually sharing a similar schema. Each group is expected to exist conceptually adjacent to another tier where one tier depends on values from another tier.
The purpose of tiers is meant to show responsibility. Primitives are the responsibility of the brand. They hold the values that the organization has chosen to use as a visual expression. Semantic tokens are the responsibility of the system. They are the contract that is held between the brand and the user experience. Component tokens (please no) are the responsibility of the component authors. For when you want to break the above contract due to a lack of agreement.
In this case we expect the primitive tier to provide a value to a semantic tier. The problem tends to be that most folks have difficulty looking at a token and determining what tier it’s meant to be in. Design token maintainers will typically organize into tiers, and someone would need to enumerate what tier each token is in. As is the case for heading-xl. In my eyes, the token could either be a primitive (because it includes a scale) or semantic (because it includes a purpose; heading). This confusion could lead to misuse.
So the question is, how could you construct a token naming convention such that it’s clear what tier a token exists within?
Brand prefixing
The easiest answer from my perspective is putting a brand prefix in front of every primitive token. Let’s say we’re creating the design token system for Yum! Brands who own restaurants such as KFC and Taco Bell. KFC and Taco Bell have different brand expressions and therefore use different colors. Let’s say we start with a collection of tokens like this:
:root {
--color-red-100:;
--color-red-200:;
--color-red-300:;
--color-red-400:;
--color-red-500:;
--color-red-600:;
--color-red-700:;
--color-red-800:;
--color-red-900:;
}The question here is, does it make sense for KFC to choose their red from this scale, and Taco Bell to choose a separate red? Or does it make more sense for these brands to have their own collections of colors that work specifically for these brands?
In my opinion, each brand should have its own collection of values and we can make that clear by explicitly saying that as a part of the token name:
:root {
--kfc-color-red-100:;
--kfc-color-red-200:;
--kfc-color-red-300:;
--kfc-color-red-400:;
--kfc-color-red-500:;
--kfc-color-red-600:;
--kfc-color-red-700:;
--kfc-color-red-800:;
--kfc-color-red-900:;
}Now it’s more clear that these are token specific to the brand. Further, you could have tooling that ensures no “brand” token appears in the product by checking for the prefix.
Back to the problem my wife was having. If you find yourself in a situation where you have heading-xl and need to separate between primitive usage and semantic, just put the brand in front: kfc-heading-xl. This represents what KFC wants as an extra large heading, and this would be assigned to the “semantic” heading-xl:
:root {
--heading-xl: var(--kfc-heading-xl);
}
h1 {
font-size: var(--heading-xl);
}You’re other option is to drop tiers altogether where all of your tokens are only semantic. This is what I recommend but, it’s easier said than done.
Did you enjoy this article?
Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.