Styles
This documentation is a work in progress. It describes prerelease software, and is subject to change.
This guide applies only if you use the default (shadow DOM) render root. If you modify your element’s render root to render into the main DOM tree instead of a shadow root, these instructions won’t apply.
If you’re using the Shady CSS polyfill, be aware that it has some limitations. See the Shady CSS README for more information.
- Use the :host CSS pseudo-class
- Style the host from the main document
- Select slotted elements with the ::slotted() CSS pseudo-element
- Use JavaScript expressions in LitElement style blocks
- Example: A small theme
Use the :host CSS pseudo-class
In a style block, use the :host
CSS pseudo-class to select the host element:
my-element.js
render() {
return html`
<style>
:host[hidden] { display: none; }
:host { display: block;
border: 1px solid black;
}
</style>
<p>Hello world</p>
`;
}
See the MDN documentation on :host and pseudo-classes for more information.
Set :host display styles
Two best practices for working with custom elements are:
-
Set a
:host
display style such asblock
orinline-block
so that your component’swidth
andheight
can be set. -
Set a
:host
display style that respects thehidden
attribute.
<style>
:host[hidden] { display: none; }
:host { display: block; }
</style>
See Custom Element Best Practices for more information.
Style shadow DOM children via properties inherited via :host
Child elements in your template will inherit CSS properties you assign to your host via the :host
CSS pseudo-class:
my-element.js
render() {
return html`
<style>
:host {
display: block;
font-family: Roboto;
font-size: 20;
color: blue;
}
</style>
<p>Inherits font styles</p>
`;
}
If your host element itself inherits properties from another element, the host’s shadow DOM children will inherit those properties in turn:
<style>
div { font-family: Roboto; }
</style>
...
<div><my-element>Will use Roboto font</my-element></div>
Style the host from the main document
You can also style the host from outside its own template.
Use the custom element tag as a selector
You can set styles for the host from the main document by using its custom element tag as a selector. For example:
index.html
<style>
my-element {
font-family: Roboto;
font-size: 20;
color: blue;
}
</style>
...
<my-element></my-element>
The :host CSS pseudo-class has higher specificity than the element’s type selector. Styles set for your host with the :host
pseudo-class from inside its own template will override styles set in the main document. For example:
index.html
<style>
my-element {
color: blue;
}
</style>
...
<my-element></my-element>
my-element.js
<style>
/* Overrides styles set for my-element in index.html */
:host {
color: red;
}
</style>
Use custom properties
Custom properties inherit down the DOM tree. You can use this to let your users apply styles and themes to your elements.
For example, the following element sets its background color to a CSS variable that uses the value of the custom property --myBackground
if it is available, and uses yellow
otherwise:
my-element.js
<style>
:host {
display: block;
background-color: var(--myBackground, yellow);
}
</style>
The user can now set the custom property --myBackground
in their main document in order to style the background of my-element
.
index.html
<style>
my-element {
--myBackground: rgb(67, 156, 144);
}
</style>
If the user has an existing app theme, they can easily apply their theme properties to my-element
:
<style>
html {
--themeColor1: rgb(67, 156, 144);
}
my-element {
--myBackground: var(--themeColor1);
}
</style>
import { LitElement, html } from '@polymer/lit-element';
class MyElement extends LitElement {
render() {
return html`
<style>
:host[hidden] { display: none; }
:host { display: block;
background-color: var(--myBackground, yellow);
color: var(--myColor, black);
padding: var(--myPadding, 8px);
}
</style>
<p>Hello world</p>
`;
}
}
customElements.define('my-element', MyElement);
See CSS Custom Properties on MDN for more information.
Select slotted elements with the ::slotted() CSS pseudo-element
Use the ::slotted()
CSS pseudo-element to select light DOM elements that have been included in shadow DOM via the <slot>
element.
-
::slotted(*)
matches all slotted elements. -
::slotted(p)
matches slotted paragraphs. -
p ::slotted(*)
matches slotted elements in a paragraph element.
import { LitElement, html } from '@polymer/lit-element';
class MyElement extends LitElement {
render() {
return html`
<style>
:host[hidden] { display: none; }
:host { display: block; }
::slotted(*) { font-family: Roboto; }
::slotted(span) { color: blue; }
div ::slotted(*) { color: red; }
</style>
<slot></slot>
<div><slot name="hi"></slot></div>
`;
}
}
customElements.define('my-element', MyElement);
Use JavaScript expressions in LitElement style blocks
You can include style information in a JavaScript expression inside a LitElement template:
render() {
return html`
<style>${this.myStyles}</style>
<p>hi world</p>
`;
}
get myStyles() {
return html`p { color: red }`;
}
Example: A small theme
index.html
<style>
html {
--themeColor1: rgb(67, 156, 144);
--themeFont: Roboto;
}
my-element {
--myColor: var(--themeColor1);
--myFont: var(--themeFont);
}
</style>
...
<my-element></my-element>
my-element.js
render() {
return html`
<style>
:host[hidden] { display: none; }
:host { display: block;
color: var(--myColor, aliceblue);
font-family: var(--myFont, Verdana);
}
${navStyles}
</style>
<ul class="navigation">
${this.menuItems.map(item => html`<li class="item">${item}</li>`)}
</ul>
`;
}
my-styles.js
export const navStyles = html`
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.navigation {
display: flex;
flex-direction: row;
}
.item {
padding: 8px;
}
`;