You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Default - The standard palette used when no other palette is specified.
Alternate - Used to differentiate alternating sections from the body, without strong emphasis or highlighting.
Accent - A complementary color used for highlights and emphasis.
Brand - The primary color for the brand.
Palettes basically link a background color to a text color with additional information if the background color is dark or light. This is very practical because it ensures that text and nested components always render with appropriate contrast. Technically, it's a difficult concept to implement, also because the CSS features light-dark() and color-scheme: light dark are not supported widely enough.
I would like to extend this concept to more colours and add more functionality to it. However, there are multiple challenges with this.
Basic idea
The Design System uses more than four different colours internally. For example for notifications, there are error, warning, info, success and neutral colours defined. The Design System components are styled with tokens, but the tokens are mapped to specific components from the Design System, which makes it hard to re-use the colour system for project-specific components. With the addition of colour-schemes, the ability to switch between light and dark mode, defining colours for project specific components becomes tricky. The Design System should offer a way to re-use defined colours beyond the four already provided helpers.
Surface palettes
This class of palette colours is intended to be used as background colours for the page itself, large sections of the page, non-interactive teasers, big popups, drawers, menus and the like. They serve to separate sections or draw attention to a specific area of the page.
These are used for interactive elements like buttons, form elements, tabs, accordion headers and clickable teasers. The definition not only contains definitions for one background and one text colour, but also provides definitions for all possible states like hover, focus, disabled, readonly, active, selected, etc.
These provide a way of defining backgrounds for signalling application state in alerts, notifications, toasts, error and success messages etc. There are two variants of signal colours: strong and subtle (naming TBD) to communicate on different levels of urgency.
A webpage can either be in light or dark mode. The user can make this choice implicit (using system default) or explicit (by using a switch on the page). Each palette will either have a light background or a dark background and that is independent of the scheme currently used by the page, for example palette-brand is always light because it's yellow in light and dark mode and for cargo it's always dark because it's dark green in both light and dark mode. Some palettes like palette-accent might also invert because they are dark in light mode and light in dark mode.
Handling these circumstances in CSS is challenging even if light-dark() would be available, even more so without it. This incurs certain limitations to palettes from the technical side.
Nesting palettes
It's impossible to write CSS selectors for infinitely nested palettes that each react to their current colour scheme context. It's only possible to define it one level deep (without overly complex selectors). This has the consequence that:
Surface palette colours stay constant when nested. In light mode, a palette-default will always have a light-grey background, even if nested on a palette-accent, that would switch the local scheme to dark. This makes it more reliable because it's easy to predict what colour a palette will have, but less flexible because the palettes only react to the page wide color-scheme and not to their context.
Token definitions
Tokens for palettes can either be defined on the component layer or on their own layer with a slim component layer.
The first approach lists all available palette tokens on the component layer which enables to set specific tokens per palette. For example surface palettes don't need any state variants while interactive palettes need a lot of additional state tokens for hover, focus etc.
The second approach would provide a layer of abstraction and leave us with a very slim token definition on the component layer. The abstraction leads to definitions that would not be necessary. Imagine the different palette colours as columns and the properties like background, foreground, border-color, scheme, background.hover, foreground.hover etc. as rows. Each cell would either have to be filled with a sensible value or left empty, which leaves room for interpretation on implementation side. The benefit of approach two would be that in Figma, whole containers (frames) of teasers could be switched from one palette to another by switching the palette layer on the frame.
The Carbon Design System implemented a color layering model that automatically alternates background colours on nested components in light mode and successively lightens colours in dark mode. This works by nesting elements with support for the layering model. Something similar would be possible with surface palettes, but would need more thought and clearer definitions on our side.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Currently, we have four palette color utilities defined.
Palettes basically link a background color to a text color with additional information if the background color is dark or light. This is very practical because it ensures that text and nested components always render with appropriate contrast. Technically, it's a difficult concept to implement, also because the CSS features
light-dark()
andcolor-scheme: light dark
are not supported widely enough.I would like to extend this concept to more colours and add more functionality to it. However, there are multiple challenges with this.
Basic idea
The Design System uses more than four different colours internally. For example for notifications, there are error, warning, info, success and neutral colours defined. The Design System components are styled with tokens, but the tokens are mapped to specific components from the Design System, which makes it hard to re-use the colour system for project-specific components. With the addition of colour-schemes, the ability to switch between light and dark mode, defining colours for project specific components becomes tricky. The Design System should offer a way to re-use defined colours beyond the four already provided helpers.
Surface palettes
This class of palette colours is intended to be used as background colours for the page itself, large sections of the page, non-interactive teasers, big popups, drawers, menus and the like. They serve to separate sections or draw attention to a specific area of the page.
https://www.figma.com/design/JIT5AdGYqv6bDRpfBPV8XR/Foundations-%26-Components-Next-Level?node-id=31-45
Interactive palettes
These are used for interactive elements like buttons, form elements, tabs, accordion headers and clickable teasers. The definition not only contains definitions for one background and one text colour, but also provides definitions for all possible states like hover, focus, disabled, readonly, active, selected, etc.
These palettes should be used on interactive surfaces only. Interactive elements should not be nested (https://accessibilityinsights.io/info-examples/web/nested-interactive/).
https://www.figma.com/design/JIT5AdGYqv6bDRpfBPV8XR/Foundations-%26-Components-Next-Level?node-id=31-149
Signal palettes
These provide a way of defining backgrounds for signalling application state in alerts, notifications, toasts, error and success messages etc. There are two variants of signal colours: strong and subtle (naming TBD) to communicate on different levels of urgency.
https://www.figma.com/design/JIT5AdGYqv6bDRpfBPV8XR/Foundations-%26-Components-Next-Level?node-id=31-193
Challenges
A webpage can either be in light or dark mode. The user can make this choice implicit (using system default) or explicit (by using a switch on the page). Each palette will either have a light background or a dark background and that is independent of the scheme currently used by the page, for example
palette-brand
is always light because it's yellow in light and dark mode and for cargo it's always dark because it's dark green in both light and dark mode. Some palettes likepalette-accent
might also invert because they are dark in light mode and light in dark mode.Handling these circumstances in CSS is challenging even if
light-dark()
would be available, even more so without it. This incurs certain limitations to palettes from the technical side.Nesting palettes
It's impossible to write CSS selectors for infinitely nested palettes that each react to their current colour scheme context. It's only possible to define it one level deep (without overly complex selectors). This has the consequence that:
palette-default
will always have a light-grey background, even if nested on apalette-accent
, that would switch the local scheme to dark. This makes it more reliable because it's easy to predict what colour a palette will have, but less flexible because the palettes only react to the page wide color-scheme and not to their context.Token definitions
Tokens for palettes can either be defined on the component layer or on their own layer with a slim component layer.
post-core-color-yellow
->post-scheme-color-surface-brand-bg
->post-theme-color-palettes-brand-bg
->post-palettes-color-brand-bg
post-core-color-yellow
->post-scheme-color-surface-brand-bg
->post-theme-color-palettes-brand-bg
->post-palettes-color-brand-bg
->post-palettes-color-bg
The first approach lists all available palette tokens on the component layer which enables to set specific tokens per palette. For example surface palettes don't need any state variants while interactive palettes need a lot of additional state tokens for hover, focus etc.
The second approach would provide a layer of abstraction and leave us with a very slim token definition on the component layer. The abstraction leads to definitions that would not be necessary. Imagine the different palette colours as columns and the properties like background, foreground, border-color, scheme, background.hover, foreground.hover etc. as rows. Each cell would either have to be filled with a sensible value or left empty, which leaves room for interpretation on implementation side. The benefit of approach two would be that in Figma, whole containers (frames) of teasers could be switched from one palette to another by switching the palette layer on the frame.
Thanks @Vandapanda for the proposal
Further ideas
Automatic alternating palettes
The Carbon Design System implemented a color layering model that automatically alternates background colours on nested components in light mode and successively lightens colours in dark mode. This works by nesting elements with support for the layering model. Something similar would be possible with surface palettes, but would need more thought and clearer definitions on our side.
Thanks @sandra-post for the idea & link
Questions
Beta Was this translation helpful? Give feedback.
All reactions