LitElement, which provides reactive properties, declarative templates via html, and Shadow DOM encapsulation out of the box.
Defining a component
Every Lit component is a class that extendsLitElement and is registered as a custom element with a tag name.
- Decorator
- customElements.define
@customElement decorator calls customElements.define() automatically. Both approaches produce the same result.
Tag names must contain a hyphen (
-). This is a requirement of the Custom Elements specification.Component class structure
A typical Lit component class has three main static/instance members:static styles
A
CSSResult or array of CSSResult values applied once to the shadow root via adoptedStyleSheets.static properties
Declares reactive properties. Each property gets an auto-generated accessor that calls
requestUpdate() when set.render()
Returns a
TemplateResult describing what the component’s shadow DOM should look like. Called on every update.Shadow DOM encapsulation
Lit renders each component into a Shadow DOM attached to the element. By default, this shadow root is created inopen mode:
shadowRootOptions to use closed mode or enable delegated focus:
What shadow DOM gives you
- Style isolation: styles defined in
static stylesdon’t leak out; external styles don’t bleed in (except via CSS custom properties and::part()). - DOM isolation:
document.querySelector()can’t reach inside a shadow root by default. - Slot composition: light DOM children provided by the consumer are projected into
<slot>elements inside the shadow root.
Rendering into the shadow root
ThecreateRenderRoot() method creates the shadow root and applies styles. LitElement overrides it to set renderOptions.renderBefore so that adoptedStyleSheets always take precedence over any inline styles:
createRenderRoot:
Public properties vs. internal state
Lit distinguishes between two kinds of reactive data:- Public properties (@property)
- Internal state (@state)
Exposed as HTML attributes and settable by consumers of your element.Use
@property() for data that element users should be able to set via HTML:As a rule of thumb: use
@property() for API surface that consumers configure, and @state() for internal bookkeeping that drives the component’s own rendering.