To bundle styles with a component, create a style sheet in the component’s folder. The style sheet must have the same name as the component. The style sheet is applied to the component automatically.
Each component can have only one style sheet. Components can’t share style sheets. Style sheets use standard CSS syntax and you can use most selectors.
With Custom Elements, web developers can create new HTML tags, beef-up existing HTML tags, or extend the components other developers have authored. The API is the foundation of web components. It brings a web standards-based way to create reusable components using nothing more than vanilla JS/HTML/CSS. Dynamic HTML and CSS rendering in Lightning Web Components (LWC) for Desktop and Mobile LWC has different lifecycle hooks which are essentially are callback methods triggered at a specific phase of a component instance’s lifecycle. Shadow DOM slots, composition Many types of components, such as tabs, menus, image galleries, and so on, need the content to render. Just like built-in browser expects items, our may expect the actual tab content to be passed. And a may expect menu items. ES Modules enable web components to be developed in a modular way that is in alignment with other industry accepted implementations for JavaScript application development. You can define the interface of your custom element in a JS file which is then included with an type='module' attribute. ES Module files are merged into one file client side.
Styles defined in a component’s style sheet 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.
Important
Before we go further, we need to understand naming. A component's folder and file names are camel case, myComponent
, myComponent.html
, and myComponent.css
. In HTML markup, camelCase maps to kebab-case. When a component renders, the <template>
tag is replaced with <namespace-component-name>
. Note that the tag includes the component's namespace. For example, a component with the template myComponent.html
in the example
namespace renders as <example-my-component>
. For more information about naming, see Component Bundles.
This example demonstrates how the CSS styles defined in a parent component don’t reach into a child.
There are two components cssParent
and cssChild
. Each component contains text in a <p>
tag. The cssParent.css
style sheet defines the p
style as xx-large
. The style applies only to the <p>
tag in the parent, not to the <p>
tag in the nested child.
A parent component can style a child component, but it styles it as a single element. A parent can’t reach into the DOM of a child. In the playground, add an example-css-child
selector to cssParent.css
that defines the background of the child component.
Tip
To access cssParent.css
in the playground, scroll to the right in the left pane header and click the filename.
In a new playground, let’s style the example-css-child
component from its own style sheet, cssChild.css
.
A component’s style sheet can reach up and style its own element. Instead of using a example-css-child
selector, use the :host
selector.
Uncomment this code in cssChild.css
. By targeting the host element with :host
, we apply styling to <example-css-child>
, from cssChild.css
.
Note
The cssParent.css
file in this playground doesn't include the example-css-child
selector. 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.
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, in a new playground, let’s rewrite our sample code to look slightly more like a real app.
Style the p
in the child component x-large
, which is just a notch smaller than the p
in the parent component. Make each item whitesmoke
except the active item, which is thistle
.
Right now, the child component contains just a static title, To Do Item. Add a <slot>
to cssChild.html
so the parent component can pass to do item text.
In the parent, add three example-css-child
components and make one active. In a real app, the active component would be the selected item. Because example-css-child
contains a <slot>
, we can pass text for each to do item.
For more information about <slot>
, see Pass Markup into Slots.
To share CSS style rules, create a module that contains only a CSS file. Import the module into the CSS file of any Lightning web component you want to style.You can import style rules from multiple CSS modules. The imported style rules are applied to the template just like non-imported style rules. Lightning Web Components supports the CSS cascade algorithm.
Create a Lightning web component that contains only a single CSS file. This component is your CSS module.
Important
Just like with any Lightning web component, the folder name and the filename must be identical.
Import the module into the CSS file of a Lightning web component.
Imported style rules are applied to the template just like non-imported style rules. All style rules cascade. In the cssSharing.html
template, the text in the <h1>
tag uses the style defined in cssLibrary.css
.
For more information about @import
, see MDN web docs: @import. MDN lists two syntaxes: @import url
and @import url list-of-media-queries
. LWC doesn’t honor the list-of-media-queries
.
The CSS scoping matches the CSS Scoping Module Level 1 standard, with a few exceptions.
:host-context()
pseudo-class function.::slotted
pseudo-element.Important
LWC uses id
values for accessibility only. When the template is rendered, id
values are transformed into globally unique values. Don't use ID selectors in JavaScript or in CSS. If you do, the selector won’t match the transformed ID and you get an error.
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 <example-parent>
element has a example-parent_parent-host
attribute.
← ES ModulesComposition →
This page assumes you’ve already read the Components Basics. Read that first if you are new to components.
Vue implements a content distribution API that’s modeled after the current Web Components spec draft, using the <slot>
element to serve as distribution outlets for content.
This allows you to compose components like this:
Then in the template for <navigation-link>
, you might have:
When the component renders, the <slot>
element will be replaced by “Your Profile”. Slots can contain any template code, including HTML:
Or even other components:
If <navigation-link>
did not contain a <slot>
element, any content passed to it would simply be discarded.
There are times when it’s useful to have multiple slots. For example, in a hypothetical base-layout
component with the following template:
For these cases, the <slot>
element has a special attribute, name
, which can be used to define additional slots:
To provide content to named slots, we can use the slot
attribute on a <template>
element in the parent:
Or, the slot
attribute can also be used directly on a normal element:
There can still be one unnamed slot, which is the default slot that serves as a catch-all outlet for any unmatched content. In both examples above, the rendered HTML would be:
There are cases when it’s useful to provide a slot with default content. For example, a <submit-button>
component might want the content of the button to be “Submit” by default, but also allow users to override with “Save”, “Upload”, or anything else.
To achieve this, specify the default content in between the <slot>
tags.
If the slot is provided content by the parent, it will replace the default content.
When you want to use data inside a slot, such as in:
That slot has access to the same instance properties (i.e. the same “scope”) as the rest of the template. The slot does not have access to <navigation-link>
‘s scope. For example, trying to access url
would not work. As a rule, remember that:
Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope.
New in 2.1.0+
Sometimes you’ll want to provide a component with a reusable slot that can access data from the child component. For example, a simple <todo-list>
component may contain the following in its template:
But in some parts of our app, we want the individual todo items to render something different than just the todo.text
. This is where scoped slots come in.
To make the feature possible, all we have to do is wrap the todo item content in a <slot>
element, then pass the slot any data relevant to its context: in this case, the todo
object:
Now when we use the <todo-list>
component, we can optionally define an alternative <template>
for todo items, but with access to data from the child via the slot-scope
attribute:
In 2.5.0+, slot-scope
is no longer limited to the <template>
element, but can instead be used on any element or component in the slot.
slot-scope
The value of slot-scope
can actually accept any valid JavaScript expression that can appear in the argument position of a function definition. This means in supported environments (single-file components or modern browsers) you can also use ES2015 destructuring in the expression, like so:
This is a great way to make scoped slots a little cleaner.