Style Components with CSS Stylesheets

To bundle a set of styles with a component, create a stylesheet with the same name as the component in the component’s folder. The stylesheet is automatically applied to the component. If you want to style a component with one or more stylesheets, configure the stylesheets static property.

You can only have one stylesheet in a component’s folder. Stylesheets use standard CSS syntax and you can use most selectors. A stylesheet can import style rules from multiple CSS modules.

Styles defined in a component’s stylesheet are scoped to the component. This rule allows a component to be reused in different contexts without losing its style. It also prevents a component’s styles from overriding styles in other parts of a page.

This example demonstrates how the CSS styles defined in a parent component don’t reach into a child. There are two components, c-parent and c-child. Each component contains an <h1> tag. The parent.css stylesheet defines the h1 style as xx-large. When you run the code, the style applies only to the <h1> tag in the parent, not to the <h1> tag in the nested child.

Parent text is extra large. Child text is normal size.

A parent component can style a child component, but it styles it as a single element. A parent can’t reach into a child. Let’s add a c-child selector to parent.css that defines a border around the child component.

The child component has a red box around it.

Now let’s style the c-child component from its own style sheet, child.css.

Before we add a selector to child.css, let’s remove the c-child selector from parent.css to remove the red box. It’s not a good practice to style components from both the component and its parent, because it can be confusing and yield unexpected results. Here is parent.css with the c-child removed.

A component’s stylesheet can reach up and style its own element, which in this example is c-child.

Instead of using a c-child selector, use the :host selector.

Child component's background is yellow.

By targeting the host element with :host, we’ve applied styling to <c-child>, from child.css.

The :host selector accepts an optional list of selectors. To match, the host element must have a class that matches the passed selector. To see how the :host selector works, let’s rewrite our sample code to look slightly more like a real app. We add a <slot> to c-child so we can pass the name of the item on the To Do List.

Let’s style the h1 in the child component, but make it large, which is a bit smaller than the xx-large h1 we defined in the parent component. Let’s also make all list items light gray except the active item, which is light green.

In the parent, let’s add three c-child components and make one active. In a real app, the active component would be the selected item.

To do list with active to do item in light green.

The CSS scoping matches the CSS Scoping Module Level 1 standard, with a few exceptions.

  • No support for the :host-context() pseudo-class function.
  • No support for the ::part pseudo-element.
  • No support for ID selectors in CSS. Make sure that id values are unique within your HTML template. When the template is rendered, id values may be transformed into globally unique values. If you use an ID selector in CSS, it won’t match the transformed ID.
  • LWC doesn’t reflect a component’s custom public properties into their corresponding HTML attributes. To give identity to a child element for styling, use a class attribute or a data-* attribute.

Scoped CSS affects performance, so use it with care. Each selector chain is scoped, and each compound expression passed to :host() is spread into multiple selectors. This transformation increases the size and complexity of the generated CSS. These increases mean more bits on the wire, longer parsing time, and longer style recalculation time.

To ensure CSS encapsulation, each element has an extra attribute, which also increases rendering time. For example, the <c-parent> element has a c-parent_parent-host attribute.

To customize a component with one or more stylesheets, add the stylesheets static property to the LightningElement constructor. This property accepts an array of stylesheets, and its default value is an empty array. You can set the stylesheets property for light DOM and shadow DOM components.

For example, to inject the header-styles.css and button-styles.css stylesheets into myComponent, configure the stylesheets static property in myComponent.js.

The first stylesheet the LWC engine injects is myComponent.css, since it's implicitly associated with the component’s template. Then the engine loads all the stylesheets associated with the stylesheets property in the order that they’re listed inside the array. Based on this configuration of stylesheets, myComponent loads its stylesheets in the following order: myComponent.css, header-styles.css, and button-styles.css.

The LWC engine caches the stylesheets array for the lifetime of the application during the component class definition. If you modify stylesheets after the component’s code is evaluated, it won’t affect the injected stylesheets.

A subclass component doesn’t automatically inherit stylesheets from a superclass component. If you want to extend stylesheets from a superclass component to a subclass component, use super.stylesheets to manually merge the superclass stylesheets with the stylesheets for the subclass component.

See Also