Because Lit components render into Shadow DOM by default, styling works differently than global page CSS. This lesson gives an overview before the dedicated lessons on the css tag, custom properties, and parts.
Shadow DOM Encapsulates Styles by Default
Any CSS defined inside a Lit component's static styles field only applies within that component's own Shadow DOM — it cannot leak out to affect the rest of the page, and page-level stylesheets cannot reach in to affect the component's internals either. This is one of Shadow DOM's core guarantees, and it's what makes Lit components genuinely reusable without CSS naming collisions (no more .card__title--variant-2 style BEM workarounds needed purely for isolation).
This encapsulation is a deliberate trade-off: it eliminates an entire category of styling bugs (accidental overrides, specificity wars) at the cost of needing explicit mechanisms — CSS custom properties and ::part() — to intentionally allow some styling to cross that boundary when a component author wants to permit it.
These styles apply only to the <span> inside this component's Shadow DOM — a page-level span { color: red; } rule elsewhere has no effect on it.
The static styles Field
static styles = css`
/* your component's scoped CSS */
`;
// Or an array of multiple style sheets:
static styles = [sharedStyles, css`/* component-specific overrides */`];
static styles is a class field (or getter) holding the result of the css tagged template function.
It accepts either a single css result or an array of them, which Lit combines for the component.
Styles defined here apply automatically to the component's Shadow DOM — no manual <style> tag needed in the template.
The :host selector targets the custom element itself, from the inside — covered in the CSS tag lesson.
Styling Mechanisms Overview
Every tool available for styling a Lit component, at a glance.
Mechanism
Purpose
`static styles = css`...`
Scoped styles for the component's own Shadow DOM
:host
Selects the custom element itself from inside its own styles
CSS custom properties
Values consumers can override from outside (theming)
::part()
Exposes specific internal elements for external styling
::slotted()
Styles top-level projected light DOM content
Adopted stylesheets
Sharing a CSSStyleSheet object across multiple components efficiently
Why Use css` Instead of a <style>` Tag in the Template?
You technically *can* put a <style> tag directly inside your render() template, but Lit's static styles mechanism is more efficient: styles declared this way are parsed once (and, where supported, shared across every instance of the component via Constructable Stylesheets) rather than being re-parsed as part of every single render pass.
Approach
Parsed
Shared Across Instances
`static styles = css`...`
Once, at class definition
Yes, via adopted stylesheets where supported
<style> inside render()
Potentially on every render
No — duplicated per instance
Some Things Still Cross the Boundary
Not everything is blocked by Shadow DOM: inherited CSS properties (like font-family, color, and line-height) do cascade in from ancestors unless explicitly overridden, and CSS custom properties (--my-var) also cross the boundary by design, which is exactly what makes them the standard theming mechanism for Web Components.
Common Mistakes
Expecting a page-level stylesheet selector to reach into a component's Shadow DOM and style its internals directly.
Putting all styles inline in a <style> tag inside render() instead of using the more efficient static styles field.
Forgetting that inherited properties like font-family and color still cascade into Shadow DOM unless the component resets them.
Not providing any theming hooks (CSS custom properties or parts), making a component impossible for consumers to restyle at all.
Key Takeaways
Shadow DOM encapsulates a Lit component's styles by default, in both directions.
static styles = css`...` is the idiomatic, efficient way to declare a component's scoped CSS.
Inherited CSS properties and custom properties are the two things that do cross the Shadow DOM boundary.
Deliberate theming mechanisms (custom properties, ::part()) exist for when you want to allow external styling.
Pro Tip
Before writing a single style rule, sketch out which parts of your component's appearance should be fixed (encapsulated, protected from page CSS) versus themeable (exposed via custom properties or parts) — deciding this upfront leads to a much cleaner styling API than retrofitting theming hooks later.
You now have an overview of Lit styling. Next, go deep on the css tagged template function itself.