Since not all browsers support Shadow DOM, LWC uses a synthetic shadow polyfill for Lightning Experience and Experience Cloud. A polyfill is code that allows a feature to work in a web browser.
If you use LWC outside of Lightning Experience or Experience Cloud, such as in Lightning Out, LWC renders in native shadow. See Compile-time Differences on the Salesforce Platform.
To understand the shadow tree, let’s look at some markup. This markup contains two Lightning web components:
#shadow-root document fragment defines the boundary between the DOM and the shadow tree. Elements below the shadow root are in the shadow tree.
Let’s look at how to work with the shadow tree in each of these areas.
CSS styles defined in a parent component don’t leak into a child. In our example, a
pstyle defined in the
todoApp.cssstylesheet doesn’t style the
pelement in the
c-todo-itemcomponent, because the styles don’t reach into the shadow tree. See CSS.
To prevent exposing a component’s internal details, if an event bubbles up and crosses the shadow boundary, some property values change to match the scope of the listener. See Event Retargeting.
- Access Elements
Elements in a shadow tree aren’t accessible via traditional DOM querying methods. Code can’t use
document.bodyto access the shadow tree of a Lightning web component. For example, code can’t call
document.querySelector()to select nodes in a Lightning web component’s shadow tree. To access its own shadow tree, a Lightning web component calls
this.template.querySelector(). See Access Elements the Component Owns.
- Access Slots
A slot is a placeholder for markup that a parent component passes into a component’s body. DOM elements that are passed to a component via slots aren’t owned by the component and aren’t in the component’s shadow tree. To access DOM elements passed via slots, call
this.querySelector(). The component doesn't own these elements, so you don’t use
template. See Pass Markup into Slots.
- Test Components
Watch Salesforce Developer Evangelist Alba Rivas explain the Shadow DOM.
Lightning Locker prevents you from breaking shadow DOM encapsulation between Lightning web components by blocking these APIs. However, in Aura components version 39.0 and earlier, Lightning Locker is disabled at the component level, so an Aura component could have code that fails.
These APIs aren’t restricted by Lightning Web Security (LWS). LWS prevents you from breaking shadow DOM encapsulation by enforcing a value of
closed on the ShadowRoot's
mode property for all components.
The Shadow DOM polyfill includes a patch to the
MutationObserver interface. If you use
MutationObserver to watch changes in a DOM tree, disconnect it or you will create a memory leak. Note that a component can observe mutations only in its own template. It can't observe mutations within the shadow tree of other custom elements.