The original link
In this article, Element and Component are used in some contexts. LitElement is essentially an implementation of WebComponents, so elements can be considered components.
How do component developers define component styles
The ShadowDOM API allows the creation of an encapsulated DOM tree on a custom element. The root node of the ShadowDOM tree is shadowRoot, and the element mounted by shadowRoot is called host element (or host).
In general, LitElement creates shadowRoot for each host element and renders the DOM structure described by the template to shadowRoot.
ShadowDOM limits the scope of CSS so that styles defined within shadowRoot only apply to DOM elements within shadowRoot and do not leak to the external DOM. In addition to CSS inheritance properties, shadowRoot isolates styles outside of it, whether they are in the main document or outside of shadowRoot.
Where to define styles
There are three ways to define the host element and its shadowDOM style:
- Static LitElement class
styles
Properties (recommended) render
Method into the HTML template<style>
The element- External style sheets, through
< link rel = "stylesheet" href = "..." >
Link to the LitElement template
Static LitElement classstyles
attribute
LitElement allows you to define static styles that can be applied to all component instances.
Static styles improve performance; they are parsed once and reused across multiple components.
If you want to style each component instance, you need to use CSS custom properties (compatibility risk, iOS9 does not support) :
- Component developers define CSS variables in shadowDOM
- The component consumer defines the values of these custom CSS variables externally
Define static styles:
import { LitElement, css, unsafeCSS } from 'lit-element';
class MyElement extends LitElement {
static get styles() {
const mainWidth = 800;
const padding = 20;
return css`
:host {
width: ${unsafeCSS(mainWidth + padding)}px;
}
`; }}Copy the code
For literal strings (red), you can simply use ${}; Variables need to be wrapped in ${unsafeCSS()}.
⚠️unsafeCSS can only be used with trusted input, otherwise there may be a security risk.
HTML template<style>
The element
Inserting
import {LitElement, property} from 'lit-element';
class MyElement extends LitElement {
@property() mainColor = 'blue';
render() {
return html`
<style>
:host {
color: The ${this.mainColor};
}
</style>
`; }}Copy the code
⚠️ do not use expressions inside
External style sheets
Load external stylesheets via the tag:
import {LitElement} from 'lit-element';
class MyElement extends LitElement {
render() {
return html`
`; }}Copy the code
There are two main points to emphasize about this approach:
- The first load causes unstyled content flicker (FOUC)
href
The path to the main document is not well suited for exposed reusable components
Write CSS styles for the Host Element and its ShadowDOM
Write styles for host elements
Host elements can style themselves with :host and :host()CSS pseudo-classes:
-
:host Selects the host element corresponding to shadowRoot
:host { display: block; color: blue; } Copy the code
-
: the host (…). This takes effect only if the selector in parentheses matches the host element
:host(.important) { color: red; font-weight: bold; } Copy the code
Two best practices for custom elements:
-
Add a display style (such as block or inline-block) to :host. The default display for :host is inline. Inline elements are sized by their contents rather than by CSS
:host { display: block; } Copy the code
-
Style :host with hidden property
:host([hidden]) { display: none; } Copy the code
Write styles for ShadowDOM
For elements within shadowRoot, use standard CSS selectors.
Internally defined CSS selectors work only inside shadowRoot, so they can do whatever they want inside. They don’t match external elements:
* {
color: black;
}
h1 {
font-size: 4rem;
}
#main {
padding: 16px;
}
.important {
color: red;
}
Copy the code
Style slotted Children
For elements inserted into shadowDOM with
slots, we can use ::slotted() pseudo-elements to select:
::slotted(*)
Matches all slot elements::slotted(p)
Matches the P elements of all slotsdiv ::slotted(*)
Matches all slot elements within div
import { LitElement, html } from 'lit-element';
class MyElement extends LitElement {
render() {
return html`
`;
}
}
customElements.define('my-element', MyElement);
Copy the code
How do component users define component styles
When using a component, the user simply uses the tag of the custom component as selector in the main document, for example:
<style>
my-element {
font-family: Roboto;
font-size: 20;
color: blue;
}
</style>.<my-element></my-element>
Copy the code
These externally defined attributes, applied to the host element, take precedence over those defined internally with :host
Three, themes,
This section describes how to use CSS inheritance and custom CSS properties for:
- Create the easily Stylable LitElement component
- Create a style theme that you can easily use to import LitElement
CSS inheritance and shadowDOM
Inheriting CSS properties (such as color,font-family, and all CSS custom properties (- *) can be inherited across shadowRoot boundaries, which means that elements can generally share important styles externally.
Component authors can take advantage of this by defining inheritance properties on the hostCSS pseudo-class that will be used on elements inside shadowRoot:
my-element.js
render() {
return html` Inherits font styles
`;
}
Copy the code
We can also define an inherited attribute change in the external main document :host, because the external element class selector takes precedence over the host pseudo-class selector, and the external style overrides the internal style:
index.html
<style>
/* Overrides the `color` property of the `:host` styles in my-element.js */
my-element {
color: blue;
}
</style>.<my-element></my-element>
Copy the code
Customize CSS properties
Custom CSS properties can be inherited along the DOM tree and can cross shadowRoot boundaries, which can be used for style and theme customization.
my-element.js
<style>
:host {
display: block;
background-color: var(--myBackground, yellow);
}
</style>
Copy the code
Index.html
<style>
my-element {
--myBackground: rgb(67, 156, 144);
}
</style>
Copy the code
The external — myBackground custom property is used on the internal my-Element
Four, summary
- For a common style of components, that is, one shared by all components, static is recommended
styles
Properties to set - For instances of components, HTML templates are recommended
<style>
Through the${this.myColor}
Implementing instance customization ::host
Pseudo classes are used to style host elements,::slotted()
Use to style the slot child elements. Styles in shadowRoot use the standard CSS selector- There are two methods for transparent transmission of attributes from the outside: CSS inherited attributes and CSS custom attributes. The custom attributes are more flexible but have certain compatibility problems