Anti-Patterns for Styling Components

Here are some common mistakes developers make when styling Lightning web components. These techniques aren’t supported and we hope it’s helpful to see some concrete examples so you can avoid them.

The most common anti-patterns are styling according to the rendered markup of Lightning base components and directly overriding SLDS classes and styles. You should also avoid querying elements using an exact class attribute string match.

When you check your browser console and see the rendered HTML of base components, it’s tempting to craft your CSS to target the elements and classes you see. However, Salesforce doesn’t support styling based on rendered output.

Salesforce needs the flexibility to redesign the internals of our components to improve performance, enhance functionality, and support accessibility. Therefore, you can’t assume that the component markup renders the same release over release. If you create styling based on such an assumption, the styling can break in the future. We document changes to the features and behavior of components, but don’t document changes to their internals.

Overriding base component styling isn't supported except when using documented styling hooks.

Here’s a common mistake, replacing an SLDS class with one of your own.

Let's say your company, Acme Widgets, uses the lightning-combobox base component in one of your custom components. You replace an SLDS class with one of Acme’s own because it's convenient, which is a common mistake. The component CSS targets the .slds-combobox__input selector.

If Salesforce changes lightning-combobox to no longer use the .slds-combobox__input selector and it causes an adverse effect on Acme component styling, it’s up to you to fix your components’ styling.

See Style Components with Lightning Design System for the supported ways to style components.

It’s simple enough to take an SLDS selector name and tweak it a little, but it’s not supported.

When you override properties for SLDS selectors, a future change in SLDS can cause unexpected results for your component styling. Lightning Design System continually improves and documents all changes in the SLDS release notes.

Here are some examples of unsupported overrides.

Instead, use the techniques discussed in Style Components with Lightning Design System.

Due to an optimization that improves render time for your Lightning web components, values for style and class attributes of your static nodes can render with extra whitespaces or unexpected characters. Update your JavaScript code that uses class or style attributes because this change can affect them.

Previously, you could include a whitespace to query elements using their class names by using an exact attribute string match.

The attribute highlight yellow had rendered as shown.

However, that attribute can now render with an extra whitespace.

Revise the JavaScript code to use a selector that disregards whitespaces.

To scope CSS within a component, LWC automatically adds attributes and classes to DOM elements. These attributes and classes are internal implementation details that can change at any time.

While it can be easy to use generated CSS scope tokens that resemble the component names, your code can break if you rely on the internals of components you don't own. Due to a performance improvement, LWC generates an obfuscated string for CSS scope tokens from Winter '24 with the format lwc-hashstring, where hashstring is a unique alphanumerical string.

The change to generate an obfuscated string for CSS scope tokens affects your custom components only when you upgrade to LWC API version 59.0. However, this change immediately affects Salesforce-authored components in Lightning Experience and Experience Builder sites, such as the components that are rendered on record pages or list views, and base Lightning components.

Don't rely on internal attributes and classes in your code or tests using this.template.querySelector(), because internal implementation can change at any time. Instead of using this.template.querySelector(), you can also use template refs (lwc:ref).

See Also