Styles
This page describes how to add styles to your component.
Your component's template is rendered to its shadow DOM tree. The styles you add to your component are automatically scoped to the shadow tree, so they don't leak out and affect other elements.
Add styles to your component
Permalink to “Add styles to your component”For optimal performance, define scoped styles in a static styles
property.
Define styles in a tagged template literal, using the css
tag function:
The styles you add to your component are scoped using shadow DOM. For a quick overview of shadow DOM styling, see Shadow DOM styling overview.
The value of the static styles
property can be:
A single tagged template literal.
An array of tagged template literals.
The static styles
property is usually the best way to add styles to your component, but there are some use cases you can't handle this way—for example, linking to an external style sheet. For alternate ways to add styles, see Define scoped styles in the template.
Expressions in static styles
Permalink to “Expressions in static styles”Static styles apply to all instances of a component. Any expressions in CSS are evaluated once, then reused for all instances.
To allow for theming or per-instance style customization, use CSS variables and custom properties to create configurable styles.
To prevent LitElement-based components from evaluating potentially malicious code, the css
tag only allows nested expressions that are themselves css
tagged strings or numbers.
This restriction exists to protect applications from security vulnerabilities whereby malicious styles, or even malicious code, can be injected from untrusted sources such as URL parameters or database values.
If you must use an expression in a css
literal that is not itself a css
literal, and you are confident that the expression is from a fully trusted source such as a constant defined in your own code, then you can wrap the expression with the unsafeCSS
function:
Only use the unsafeCSS
tag with trusted input. Injecting unsanitized CSS is a security risk. For example, malicious CSS can "phone home" by adding an image URL that points to a third-party server.
Inheriting styles
Permalink to “Inheriting styles”Using an array of tagged template literals, a component can inherit the styles from a LitElement superclass, and add its own styles:
Sharing styles
Permalink to “Sharing styles”You can share styles between components by creating a module that exports tagged styles:
Your element can then import the styles and add them to its static styles
property:
You can also import an external style sheet by adding a <link>
element to your template, but this has a number of limitations. For details, see Import an external stylesheet.
Shadow DOM styling overview
Permalink to “Shadow DOM styling overview”This section gives a brief overview of shadow DOM styling.
Styles you add to a component can affect:
- The shadow tree (your component's rendered template).
- The component itself.
- The component's children.
Style the shadow tree
Permalink to “Style the shadow tree”LitElement templates are rendered into a shadow tree by default. Styles scoped to an element's shadow tree don't affect the main document or other shadow trees. Similarly, with the exception of inherited CSS properties, document-level styles don't affect the contents of a shadow tree.
When you use standard CSS selectors, they only match elements in your component's shadow tree.
Style the component itself
Permalink to “Style the component itself”You can style the component itself using special :host
selectors. (The element that owns, or "hosts" a shadow tree is called the host element.)
To create default styles for the host element, use the :host
CSS pseudo-class and :host()
CSS pseudo-class function.
:host
selects the host element.:host(selector)
selects the host element, but only if the host element matches selector.
Note that the host element can be affected by styles from outside the shadow tree, as well, so you should consider the styles you set in :host
and :host()
rules as default styles that can be overridden by the user. For example:
Style the component's children
Permalink to “Style the component's children”Your component may accept children (like a <ul>
element can have <li>
children). To render children, your template needs to include one or more <slot>
elements, as described in Render children with the slot element.
The <slot>
element acts as a placeholder in a shadow tree where the host element's children are displayed. For example:
Use the ::slotted()
CSS pseudo-element to select children that are included in your template via <slot>
s.
::slotted(*)
matches all slotted elements.::slotted(p)
matches slotted paragraphs.p ::slotted(*)
matches slotted elements where the<slot>
is a descendant of a paragraph element.
Note that only direct slotted children can be styled with ::slotted()
.
Also, children can be styled from outside the shadow tree, so you should regard your ::slotted()
styles as default styles that can be overridden.
Watch out for limitations in the Shady CSS polyfill around slotted content! See the Shady CSS limitations for details on how to use the ::slotted()
syntax in a polyfill-friendly way.
Configurable styles with custom properties
Permalink to “Configurable styles with custom properties”Static styles are evaluated once per class. Use CSS variables and custom properties to make styles that can be configured at runtime:
See the section on CSS custom properties for more information.
Define scoped styles in the template
Permalink to “Define scoped styles in the template”We recommend using static styles for optimal performance. However, sometimes you may want to define styles in the LitElement template. There are two ways to add scoped styles in the template:
- Add styles using a
<style>
element. - Add styles using an external style sheet.
Each of these techniques has its own set of advantages and drawbacks.
In a style element
Permalink to “In a style element”We recommend using static styles for optimal performance. However, static styles are evaluated once per class. Sometimes, you might need to evaluate styles per instance.
We recommend using CSS properties to create customizable styles. However, you can also include <style>
elements in a LitElement template. These are updated per instance.
Expressions and style elements
Permalink to “Expressions and style elements”The most intuitive way to evaluate per-instance styles has some important limitations and performance issues. We consider the example below to be an anti-pattern:
Expressions inside a <style>
element won't update per instance in ShadyCSS, due to limitations of the ShadyCSS polyfill. See the ShadyCSS readme for more information.
Additionally, evaluating an expression inside a <style>
element is inefficient. When any text inside a <style>
element changes, the browser must re-parse the whole <style>
element, resulting in unnecessary work.
If you need to evaluate expressions inside a <style>
element, use the following strategy to avoid creating performance problems:
Separate styles that require per-instance evaluation from those that don't.
Evaluate per-instance CSS properties by creating an expression that captures that property inside a complete
<style>
block. Include it in your template.
Example
Import an external stylesheet
Permalink to “Import an external stylesheet”We recommend placing your styles in a static styles
property for optimal performance. However, you can include an external style sheet in your template with a <link>
:
There are some important caveats though:
The ShadyCSS polyfill doesn't support external style sheets.
External styles can cause a flash-of-unstyled-content (FOUC) while they load.
The URL in the
href
attribute is relative to the main document. This is okay if you're building an app and your asset URLs are well-known, but avoid using external style sheets when building a reusable element.
Dynamic classes and styles
Permalink to “Dynamic classes and styles”One way to make styles dynamic is to add bindings to the class
or style
attributes in your template.
The lit-html library offers two directives, classMap
and styleMap
, to conveniently apply classes and styles in HTML templates.
For more information on these and other lit-html directives, see the documentation on lit-html built-in directives.
To use styleMap
and/or classMap
:
Import
classMap
and/orstyleMap
:Use
classMap
and/orstyleMap
in your element template:
classMap syntax
Permalink to “classMap syntax”classMap
applies a set of classes to an HTML element:
styleMap syntax
Permalink to “styleMap syntax”styleMap
applies a set of CSS rules to an HTML element:
To refer to hyphenated properties such as font-family
, use the camelCase equivalent (fontFamily
) or place the hyphenated property name in quotes ('font-family'
).
To refer to custom CSS properties such as --custom-color
, place the whole property name in quotes ('--custom-color'
).
Inline style or CSS | styleMap equivalent |
---|---|
background-color: blue; | backgroundColor: 'blue' or 'background-color': 'blue' |
font-family: Roboto, Arial, sans-serif; | fontFamily: 'Roboto, Arial, sans-serif' or 'font-family': 'Roboto, Arial, sans-serif' |
--custom-color: #FFFABC; | '--custom-color': '#FFFABC;' |
--otherCustomColor: #FFFABC; | '--otherCustomColor': '#FFFABC;' |
color: var(--customprop, blue); | color: 'var(--customprop, blue)' |
Examples
Inline style syntax:
Equivalent CSS syntax:
Equivalent styleMap
syntax:
Theming
Permalink to “Theming”Use CSS inheritance to propagate style information to LitElement components and their rendered templates.
Use CSS variables and custom properties to configure styles per-instance.
CSS inheritance
Permalink to “CSS inheritance”CSS inheritance lets parent and host elements propagate certain CSS properties to their descendents.
Not all CSS properties inherit. Inherited CSS properties include:
color
font-family
and otherfont-*
properties- All CSS custom properties (
--*
)
See CSS Inheritance on MDN for more information.
You can use CSS inheritance to set styles on an ancestor element that are inherited by its descendents:
Similarly, host elements pass down inheritable CSS properties to their shadow trees.
You can use the host element's type selector to style it:
You can also use the :host
CSS pseudo-class to style the host from inside its own template:
Type selectors have higher specificity than :host.
An element type selector has higher specificity than the :host
pseudo-class selector. Styles set for a custom element tag will override styles set with :host
and :host()
:
CSS custom properties
Permalink to “CSS custom properties”All CSS custom properties (--custom-property-name
) inherit. You can use this to make your component's styles configurable from outside.
The following component sets its background color to a CSS variable. The CSS variable uses the value of --my-background
if it's available, and otherwise defaults to yellow
:
Users of this component can set the value of --my-background
, using the my-element
tag as a CSS selector:
--my-background
is configurable per instance of my-element
:
If a component user has an existing app theme, they can easily set the host's configurable properties to use theme properties:
See CSS Custom Properties on MDN for more information.
A simple example theme
Permalink to “A simple example theme”index.html
my-element.js