::part and exportparts
The part="name" attribute marks an element inside the shadow root as a named styling hook. Page CSS can then target it with the ::part(name) pseudo-element on the host — crossing the shadow boundary without losing encapsulation for everything else. The component author controls exactly which internals are exposed.
<theme-card></theme-card>Page CSS uses ::part() to style the exposed internals:
theme-card::part(title) { color: #7c3aed; font-size: 1.2rem; font-weight: bold; }theme-card::part(body) { color: #374151; font-size: 0.95rem; margin-top: 0.5rem; }The component’s own shadow stylesheet should not include these part styles — it only sets structural or default layout rules. The ::part() rules live entirely in page CSS (or in the css prop of LivePreview), and they win because of the explicit opt-in.
exportparts
Section titled “exportparts”When a component composes another custom element internally, its shadow-DOM children’s parts are not automatically visible to the page. The exportparts attribute re-exports inner parts under new names:
<outer-card exportparts="label: card-label"></outer-card>Now page CSS can write outer-card::part(card-label) to reach the inner component’s label part without needing to know the inner element’s tag name.
The css prop below is injected as a <style> block in the page, outside the component’s shadow root — exactly where ::part() rules belong.