This document defines the format for creating new design tokens that will be most effective for administration in Theme Designer as well as the locations that the tokens are required to provide similar theme control as TDv1. The words CSS Custom Property and Design Token are used interchangeably in this document and refer to the same thing, “named entities that represent atomic design values, and convey design decisions though their structure”.
The CSS Custom Variable you create should tokenize the association between a customizable value in the UI and the overarching Aspenware Design System.
1. Considerations
Multiple considerations were taken into account when determining both the properties to include and the format of the property names. The primary considerations include:
Reusability - abstraction that allows for property reuse.
Intuitive scoping - the scoping should be intuitive and easily extendable.
Standardization - the naming should follow a well established industry standard.
Design system adaptability - the naming should be abstracted enough to be easily adapted to a design system
Coverage for existing themes - the properties should give coverage to be able to adequately reproduce existing themes during a theme migration.
2. CSS Custom Prop Scoping
a. Scoping to :root
All CSS vars that you want to expose in a theme must be scoped to :root
. This is very important. :root
is a psuedo that refers to the page document itself. Any properties that are scoped to a level other than root will have a higher priority than :root
and will override any values applied by Theme Designer. It is fine to scope private variables (those not using --ads
), but be aware that Theme Designer will not have control over them.
3. Design Token Custom Prop Naming
Our theme based CSS vars MUST be prefixed with --ads
for name spacing purposes. Vars without that prefix will not be exposed by TD. For Aspenware design system properties that you do not want exposed by Theme Designer, use the prefix --adx
.
The format varies slightly between vars that are scoped to DOM elements and those that are general theme properties. These formats are aligned with (Block, Element, Modifier) model and industry recommendations[1][2][4]. Adopting this standard ensures we are not reinventing the wheel. At a high level, these groups are defined as:
Namespaces (
--ads
,--adx
, etc) are prepended first.Block levels (
*-input
,*-page
,*-brand
, etc) come after the namespace. See Section E of this guide for available block level names to use.Element levels (
*-title
,*-border
,*-button
,*-plp
,*-checkout
) are a backbone in the middle. Levels within Elements vary based on preferences for hierarchical strictness, for example, a page name, or a specific category that a var applies to.Modifiers (
*-active
,*-error
,*-hover
) are applied before the property type and are optional.Properties (
*-color
,*-margin
,*-backgroundcolor
, etc…) are placed at the end and defines the css property that the design tokens value is typed as. Properties must be lower case and concatenated. This segment of the token will be used to determine the control type and property name to be displayed in the UI.
A. Naming Requirements
Keep token names as concise as possible
Scope them to the top level tokens defined in section E of this document!
In order to limit the amount of top level accordions (categories) in TD, DO NOT add any additional top level categories beyond those defined in section E of this document
Make your var names make relational sense. When users open TD, we want them to intuitively know that if they need to find the setting for the Card Header Color on the PDP page, in TD they should go to Page → PDP → Card → Header. And so the prop name for that is
--ads-page-pdp-card-header-color
. That relationship in TD is defined by your variable name!Use full words to describe the elements (
-button-
instead of-btn-
for example)All tokens (CSS Custom vars) that you want Theme Designer to consume must be prefixed with
--ads
Props that you dont want exposed to TD, prefix with
--adx
instead
It is recommended to not nest your token names more than 4-5 levels deep or you will create “accordion hell” for your users in the TD interface when trying to drill down to the controls.
Try to focus on reusability of token names by avoiding high levels of specificity whenever possible.
When you do need a high level of specificity, place vars that are scoped to specific pages under
--ads-page-<name of page>-*
Property types must be the last element in the token and those that are multi-word must be lower case concatenated.
Test your variable name in TD when you are done to make sure it works and appears in the proper category.
For example:background-color → backgroundcolor
flex-direction → flexdirection
font-family → fontfamily
text-align → textalign
text-decoration → textdecoration
min-height → minheight
Theme Designer has internal mappings to convert the concatenated prop type for all common CSS properties back into delimited formats for an optimized user experience whenever the prop names are used in the UI.
B. Token Names Determine the Control Type
The last element in the CSS Prop/Token name determines the prop that will be displayed when consumed by Theme Designer. The following table defines that relationship. Note that “brand” scoped vars use different components than non “brand” vars.
The only prop types that will display in Theme Designer for Brand Props at this time are *-color
, *-favicon
, and *-fontfamily
. Any other --ads-brand
prop types added will not display controls in the TD app. Use non --ads-brand
categories for additional prop types. See table below.
The default widget that Theme Designer will display for all non --ads-brand
color related vars is the Color Widget which allows switching between the Color Picker Tool and the Brand Color Swatches. You can set the Color Picker Tool to be the displayed option by adding “p” after any color property (eg. *-backgroundcolorp
).
Additional mappings can be added in the Theme Designer Environment file as needed.
For this CSS property… | Use this element property type… | And this input type will be displayed |
---|---|---|
Brand (--ads-brand-*) – ONLY THESE PROP TYPES WILL DISPLAY IN THE BRAND SECTION | ||
Color |
| Color Picker Widget |
Favicon |
| Image Upload Widget |
Font Family |
| Font Configuration Widget |
Non-Brand (--ads-*) | ||
Align Content |
| Flex Align Content Menu |
Align Items |
| Flex Align Items Menu |
Aspect Ratio |
| Image aspect ratio text input with the label of “Aspect ratio” |
Background Image |
| Image Upload Widget |
Border Color |
| Color Widget (Color picker / Swatches) Color Picker toggled for |
Background Color |
| Color Widget (Color picker / Swatches) Color Picker toggled for |
Color (Text Color) |
| Color Widget (Color picker / Swatches) Color Picker toggled for |
Display |
| Display Menu |
Flex Direction |
| Flex Direction Menu |
Flex Wrap |
| Flex Wrap Menu |
Font Family |
| Font Selection Menu |
Font Style |
| Font Style Menu |
Font Weight |
| Font Weight Menu |
Justify Content |
| Flex Justify Content Menu |
Position |
| Position Menu |
Text Align |
| Text Align Menu |
Text Justify |
| Text Justify Menu |
Text Transform |
| Text Transform Style Menu |
Visible |
| Visibility Menu |
Vertical Align |
| Vertical Align Menu |
All Others |
| Text Input Field |
C. Token Format Requirements
Tokens specific to a nested element may include both component name and element name, much like the BEM CSS methodology[6]. The double dash before the property suffix is used for parsing control types to display in Theme Designer.
Format:
--ads-{block type}-{element prefix(optional)}-{element type}-{modifier/state(optional)}-{property}
Example:
--ads-card-action-button-hover-backgroundcolor
Breakout:
--ads -card -action -button -hover -backgroundcolor
namespace | block-type | el-prefix | element-type | modifier | property
D. Token Names Generate Field and Accordion Labels
The token names are also used to generate the field and accordion labels in TD, so keep this in mind when creating the CSS Prop names. In general, the last segment of the prop/token name is used to generate the input label and the previous segments are used to generate the nested accordion labels. As previously mentioned in this document, concatenated prop types will be automatically formatted (spaces inserted and capitalized) for readability in the Theme Designer UI.
E. Existing Top Level CSS Variable/Token Parts
In order to keep TD usable and free of dozens of top level options, DO NOT add any additional top level vars without team vetting. Try to place vars under existing categories. For example, if its an attribute that applies to a specific page, put it under --ads-page-<name of page>-*
--ads-border-*
: Used for vars that style global border related properties (width, color, radius, etc). These are globals. You can also have scoped ones in your “--ads-page-<name of page>-*
” vars that inherit from these global border styles.--ads-brand-*
: Used for global brand vars (DO NOT ADD ANY ADDITIONAL BRAND PROPS)--ads-breadcrumbs-*
: Used to for vars assigned to the PUI breadcrumbs--ads-calendar-*
: Used for vars assigned to the PUI calendar--ads-font-*
: Used for global font vars. These are globals. You can also have scoped ones in your “--ads-page-<name of page>-*
” vars that inherit from these global font styles.--ads-footer-*
: Used for vars assigned to the global page footer (simple footer).--ads-headings-*
: Used for vars that style H1-H6 Headings. These are globals. You can also have scoped ones in your “--ads-page-<name of page>-*
” vars that inherit from these global heading styles.--ads-header-*
: Used for vars assigned to the PUI Header--ads-hero-*
: Used for vars assigned to the NOP PLP hero--ads-input-*:
Used for vars assigned to global input components--ads-loader-*:
Used for vars assigned to the NOP page loader--ads-page-*
: Used for vars assigned to individual pages (must be followed by the page name)--ads-plugins-*
: Used for vars assigned to styling Various NOP plugins--ads-sidebar-*
: Used for vars assigned to the PUI Sidebar--ads-tabs-*
: Used for vars assigned to styling the category tabs on NOP PLPs
F. Label Map
Token parts can be formatted to appear a specific way in the TD application. This is configured in the TD Application Environment File src/environment/index.ts
.
For example you want to add a CSS variable named --ads-page-somepage-title-fontsize
and you want the label for the somepage
section to display as Some Page
in the TD Application. All you need to do is add the CSS variable name to your CSS and we can add the label format to the label map in Theme Designer app for the next TD release. Just create a card for the Platform Team and we will get it added!
List of currently mapped labels that are available to use: cssNameMap: {
alignitems: 'align items',
aspectratio: 'aspect ratio',
bordercolor: 'border color',
bordercolorp: 'border color',
bordertop: 'border top',
borderbottom: 'border bottom',
borderleft: 'border left',
borderright: 'border right',
borderradius: 'border radius',
borderwidth: 'border width',
backgroundimage: 'background image',
backgroundcolor: 'background color',
backgroundcolorp: 'background color',
brandfooter: 'brand footer',
colorp: 'color',
dropshadow: 'drop shadow',
boxshadow: 'drop shadow',
flexdirection: 'flex direction',
fontfamily: 'font family',
fontsize: 'font size',
fontstyle: 'font style',
fontweight: 'font weight',
groupmembers: 'group members',
herodisplay: 'display',
heroheight: 'height',
justifycontent: 'justify content',
lineheight: 'line height',
minheight: 'min height',
maxheight: 'max height',
minwidth: 'min width',
maxwidth: 'max width',
marginleft: 'margin left',
marginright: 'margin right',
margintop: 'margin top',
marginbottom: 'margin bottom',
paddingleft: 'padding left',
paddingright: 'padding right',
paddingtop: 'padding top',
paddingbottom: 'padding bottom',
pdp: 'PDP',
plp: 'PLP',
positiontop: 'position top',
positionbottom: 'position bottom',
positionleft: 'position left',
positionright: 'position right',
publicui: 'public ui',
simpleheader: 'simple header',
simplefooter: 'simple footer',
textcolor: 'text-color',
textcolorp: 'text-color',
textalign: 'text align',
textdecoration: 'text decoration',
textjustify: 'text justify',
textoverflow: 'text overflow',
texttransform: 'text transform',
verticalalign: 'vertical align'
},
4. References
[1]. https://www.imarc.com/blog/block-property-modifier-a-bem-like-css-custom-properties-methodology
[2]. https://blog.logrocket.com/a-guide-to-theming-in-css/
[3]. https://ionicframework.com/docs/theming/themes
[4]. https://github.com/halfmoonui/halfmoon/blob/master/css/halfmoon-variables.css#L96-L123
[5]. Naming Design Tokens - Lukas Opperman
[6] https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676