Introduction
This document helps developers using the Salesforce Lightning Design System (SLDS) or base Lightning components to ensure that their custom components align with the color-contrast changes released in Summer '23 and continuing in Winter '24. Follow the guidelines in this document to avoid visual regressions in your custom components.
Why is this happening?
Salesforce is updating the color contrast of non-text functional UI elements to meet our commitments to accessibility. These changes help users discern functional UI elements, making Salesforce easier to use for people with low vision.
Web Content Accessibility Guidelines (WCAG) are a series of web accessibility guidelines published by the Web Accessibility Initiative (WAI) of the World Wide Web Consortium (W3C). The guidelines include criteria for non-text contrast. Good color contrast means that all users can more easily see the content on any device or in any lighting conditions.
We started the color-contrast changes in Summer '23. We will continue the rollout in Winter '24 to all pages in Lightning Experience and the changes will also apply to base Lightning components used in a custom component (safe harbor).;
What is changing?
New global color styling hooks have been added to SLDS.
Base Lightning components and SLDS component blueprints have updated color values using global color styling hooks.
Icons have updated background colors for improved color contrast.
To make your custom components consistent with the color-contrast changes:
RedAll functional usage of red is Red-40 (ex. destructive button background, icons, text, badges, etc)
Any other states use Red-30 (ex. hover state)
All instances of Orange-70 have moved to Orange-60
Background for Path has moved from Green-70 to Green-60
All links have moved from Blue-50 to Blue-40
All links hover states have moved from Blue-40 to Blue-30
All functional borders have moved from Neutral-80 to Neutral-50
Glossary
Before we talk about how to update custom components to look and feel the same as the changes in the Salesforce Lightning Design System (SLDS) and Lightning Experience, let's align on some terminology.
Base Lightning ComponentsThe set of shared components provided by Salesforce to help build more consistent and high-quality UI. See the full list in the Component Library.
SLDSThe Salesforce Lightning Design System (SLDS) is a collection of design guidelines, component specifications, and production CSS that provides a consistent look and user experience for Salesforce apps.
SLDS BlueprintsA blueprint is a set of specifications for how to implement a UI component that uses SLDS.
A component is said to "implement a blueprint" when its markup matches the SLDS specification, and it uses SLDS classes like .slds-button
The full name for blueprints is component blueprints. People often refer to them as just components, but that's not entirely accurate. Components are generally fully functional, but the HTML5 and CSS in SLDS are static. You must integrate an SLDS blueprint with a JavaScript framework before a user can interact with it.
Custom PropertiesIn CSS, a custom property is a way to create shared values using the --
syntax. Examples include --lwc-colorBorder
and --slds-c-button-text-color
.
Styling hooks are CSS custom properties that are used by SLDS to make styling customizable in predictable ways. There are two types of styling hooks: global and component-level.
Global color styling hooks (--slds-g-*
) are pre-defined values for usage globally in an app. For example, to rebrand your application, use global hooks to make a change across all the components you are using.
Component-level styling hooks (--slds-c-*
) enable you to update properties in a specific component. For example, to make one single button have a thicker border, edit the component hook for that button, and it won't affect any other components.
Assign styling hooks with the var()
syntax in LWC. This makes your CSS simpler and easier to maintain.
Design tokens are shared values used in CSS. Design tokens help to maintain a scalable and consistent UI. When you use a token, each instance of the token is automatically updated every time that token is updated in SLDS, with no manual updates required. Using tokens to represent design attributes makes it easy for the design system team to update and scale design elements across web and native applications.
Replace design tokens with global color styling hooks, where possible.
Aura Design TokensHistorically, you could create custom Aura tokens if the SLDS design tokens didn't satisfy your design needs. However, using an Aura design token makes your custom UI less maintainable. Replace custom Aura tokens with SLDS styling hooks. For details, see Custom Component with Custom Tokens.
Finding Styling Hooks
To replace a hard-coded color value or a design token with the closest global color styling hook:
Look for global color styling hooks that have the same semantic meaning as the value that you're replacing. For example, if you are using a styling hook to apply colors for error messages, narrow your search down to styling hooks in the "error" category.
From the styling hooks category, select the global color styling hook that has the closest color match to the value that you're replacing.
Migration Guide
This guide lists different classifications of custom components with details on how to handle each migration scenario to align with the color-contrast changes.
Look through the classifications of custom components to identify if any of them apply to your custom Aura or Lightning web components. Find a list of your custom components from Setup. In the Quick Find box, enter Lightning Components, and then select Lightning Components.
Use the recommended approach to update your custom components.
1. Base Lightning Component
You use a Lightning web component or an Aura component without any additional overrides. Here's an example of a custom Lightning web component.
<!-- Markup -->
<template>
<lightning-button>Save</lightning-button>
</template>
Nothing. Color updates happen for free as the base Lightning components implement SLDS blueprints.
2. Custom Component with SLDS Blueprint
You use a custom component that implements a SLDS blueprint and only use SLDS classes for styling. Here's an example of a custom Lightning web component.
<!-- myComponent.html -->
<template>
<button class="slds-button slds-button_neutral">Save</button>
</template>
Nothing. Color updates happen for free if your component exactly implements an SLDS blueprint.
3. Custom Component with Partial SLDS Blueprint
This scenario is similar to 2. Custom Component with SLDS Blueprint, but you use a custom component that partially implements an SLDS blueprint or uses more than SLDS classes for styling. Here's an example of a custom Lightning web component.
<!-- Markup -->
<template>
<button class="slds-button slds-button_neutral my-class">Save</button>
</template>
/* CSS */
.my-class {
color: #ccc; <-- This value needs to get updated to meet WCAG guidelines
margin-left: 1rem;
}
You may need to update colors in your custom CSS if you see visual regressions.
If a base Lightning component exists for that blueprint and variant, we recommend replacing your custom component with the base Lightning component.
If you need to customize component styling, we recommend that you use --slds styling hooks for any hardcoded color values. If the hardcoded color value doesn't have an exact match in styling hooks, consider using the styling hook that has the closest matching color value.
You may want to check for sufficient color contrast for the component before updating the hardcoded value to a styling hook. The Stark Accessibility Checker has a free color contrast tool that's available as a browser extension in multiple browsers. For Chrome, get the extension at the chrome web store.
Color changes to SLDS classes happen for free. Because changes are scoped to color, these classes should otherwise continue to function, as expected.
In this example, the custom CSS class .my-class
overrides a value from .slds-button_neutral
. You should update the value associated with the custom class to have better color contrast. The entire implementation would also be more maintainable if you replace it with a base Lightning component and use the --slds-c-button-text-color
styling hook to make an accessible override.
Note: If no styling hook exists for the hard coded value, we recommend using the styling hook that has the closest matching color value.
<!-- Fixed Markup -->
<template>
<lightning-button class="slds-m-left_medium">Save</lightning-button>
</template>
/* Fixed CSS */
:host {
--slds-c-button-text-color: var(--slds-g-color-neutral-base-80, #C9C9C9);
}
4. Custom Component with SLDS Tokens or Classes
You use a custom component that either directly uses SLDS tokens within custom CSS or uses SLDS classes in the markup. Here's an example of a custom Lightning web component.
<!-- Markup -->
<template>
<button class="my-button">Save</button>
</template>
/* CSS */
.my-button{
border-color: var(--lwc-colorBorder);
}
You may need to replace tokens in custom CSS with the relevant global color styling hooks, as necessary.
In this example, the token t(colorBorder)
is intended for decorative borders like cards and dividers. It should be replaced with a styling hook that's aligned with the SLDS Button blueprint.
/* Fixed CSS
* Closest matching styling hooks for t(colorBorder)
*/
.my-button{
border-color: var(--slds-g-color-neutral-base-50, #747474);
}
5. Custom Component with Custom Tokens
You use a custom component that uses custom Aura design tokens. Here's the definition of a custom Aura design token and a custom component's CSS that references the custom token.
<!-- Custom Aura token -->
<aura:tokens>
<aura:token name="myBackgroundColor" value="#f4f6f9"/>
</aura:tokens>
<!-- Markup -->
<template>
<div class="my-div">...</div>
<template>
/* CSS */
.my-div{
background-color: t(myBackgroundColor);
}
/* or */
.my-div{
background-color: var(--c-myBackgroundColor);
}
We recommend replacing custom design tokens with SLDS styling hooks, where possible. When using styling hooks, use a hook that has the right semantic context. For example, a hook such as --slds-g-color-border-base-1
should only be used for borders. This approach ensures that your product remains consistent with Salesforce's styling as future color updates occur.
If you must keep your custom token for whatever reason, double check that your custom token hasn't experienced any visual regressions.
In this example, the token t(myBackgroundColor)
is using an outdated color value from SLDS. The current Lightning visual language no longer uses this color. The custom token should be replaced with the closest color from the list of styling hooks. In this example, slds-g-color-neutral-base-95: #f3f3f3
is the closest matching SLDS Styling hook.
/* CSS Fixed */
.my-div{
background-color: var(--slds-g-color-neutral-base-95, #f3f3f3);
}
6. Custom Component with Hard-coded Values
You use a custom component that uses a hard-coded color value like #444
or rgb(68,68,68)
. Your code might look like example 3 above.
We recommend replacing hard-coded colors with styling hooks if an analogous color exists. When selecting tokens, be sure to use semantic tokens in ways that preserve their meaning. For example --slds-g-color-border-base-1
should only be used as the border color of form elements. If you want to keep your hard-coded color value, verify that these colors have not experienced any visual regressions.
Note: Fallback values can remain as hard-coded color values. The var()
function accepts two arguments: a CSS custom property and an optional fallback value. In this example, --slds-c-badge-color-background
is the first argument, the CSS custom property, and #ECEBEA
is the second argument, the fallback value.
var(--slds-c-badge-color-background, #ECEBEA)
7. Base Component with --lwc override
You use a base Lightning component and you're overriding a --lwc
token to customize the style of one or more components. Here's an example of a custom Lightning web component.
<!-- Markup -->
<template>
<lightning-radio-group name="radioGroup"
label="Radio Group"
options={options}
value={value}
type="button"></lightning-radio-group>
</template>
/* CSS */
:host {
--lwc-colorBorder: red;
}
NOTE: This is not a recommended way to customize components and there is no guarantee that customizations made in this way will continue to function.
What do you need to do?Check if you are overriding and
--lwc
tokens for any of these components.Replace each overridden
--lwc
token with a--slds
styling hook.
In this example, overriding --lwc-colorBorder
to red turns all the button borders red. The SLDS team updated this component variant to use a global color styling hook so this override will stop working. In this case, simply use --slds-g-color-border-base-4
under the selector scope to override the border color.
// CSS fixed
:host {
--slds-g-color-border-base-4: red;
}
8. UI Namespace Components
You are using ui components such as ui:inputText
or ui:menu
.
UI namespace components were deprecated and should be replaced by their counterparts from the lightning namespace. See here for more info.
Summary
Check for visual regressions by looking at pages that contain custom components.
Replace hard-coded color values with global color styling hooks, where possible.
Replace design tokens with global color styling hooks, where possible.
Replace
--lwc
styling hooks with global color styling hooks.If there's no exact styling hook match for the hard-coded color value, use the closest available matching styling hook.
Pick styling hooks that correspond to the context of usage. For example, when replacing the hard-coded value of
#747474
with a styling hook, there are two alternatives to choose from--slds-g-color-border-base-4
or--slds-g-color-neutral-base-50
. We recommend that you use--slds-g-color-border-base-4
for the CSS styling context of "border" rather than--slds-g-color-neutral-base-50
.Use other categories of Styling hooks also beyond color Styling hooks for the hardcoded values.
We recommend using a hardcoded fallback value in
var(..)
statement in case a legacy browser cannot read the styling hook or design token. This is optional.Example: var(--slds-g-color-neutral-base-50, #747474);
We recommend any color customizations that you make meet WCAG 2.1 text and non-text color contrast standards.
NPM Packages and Assets with New Accessible Colors
There's a separate version of the SLDS NPM package and other assets that have the new accessible colors. Below are the links to the updated packages. The main branch for npm packages and Lightning Design System zip's will be updated with the new accessible colors on 10/13/23.