# Shadow DOM styling Shadow DOM may include both ` Hello! ``` ## Cascading The shadow host (`` itself) resides in the light DOM, so it's affected by the main CSS cascade. If there's a property styled both in `:host` locally, and in the document, then the document style takes precedence. For instance, if in the document we had: ```html ``` ...Then the `` would be without padding. It's very convenient, as we can setup "default" styles in the component `:host` rule, and then easily override them in the document. The exception is when a local property is labelled `!important`, for such properties, local styles take precedence. ## :host(selector) Same as `:host`, but applied only if the shadow host matches the `selector`. For example, we'd like to center the `` only if it has `centered` attribute: ```html run autorun="no-epub" untrusted height=80 Centered! Not centered. ``` Now the additional centering styles are only applied to the first dialog ``. ## :host-context(selector) Same as `:host`, but applied only if the shadow host or any of its ancestors in the outer document matches the `selector`. E.g. `:host-context(.dark-theme)` matches only if there's `dark-theme` class on `` on above it: ```html ... ``` To summarize, we can use `:host`-family of selectors to style the main element of the component, depending on the context. These styles (unless `!important`) can be overridden by the document. ## Styling slotted content Now let's consider the situation with slots. Slotted elements come from light DOM, so they use document styles. Local styles do not affect slotted content. In the example below, slotted `` is bold, as per document style, but does not take `background` from the local style: ```html run autorun="no-epub" untrusted height=80
*!*John Smith*/!*
``` The result is bold, but not red. If we'd like to style slotted elements in our component, there are two choices. First, we can style the `` itself and rely on CSS inheritance: ```html run autorun="no-epub" untrusted height=80
*!*John Smith*/!*
``` Here `

John Smith

` becomes bold, because CSS inheritance is in effect between the `` and its contents. But not all CSS properties are inherited. Another option is to use `::slotted(selector)` pseudo-class. It matches elements based on two conditions: 1. The element from the light DOM that is inserted into a ``. Then slot name doesn't matter. Just any slotted element, but only the element itself, not its children. 2. The element matches the `selector`. In our example, `::slotted(div)` selects exactly `
`, but not its children: ```html run autorun="no-epub" untrusted height=80
John Smith
``` Please note, `::slotted` selector can't descend any further into the slot. These selectors are invalid: ```css ::slotted(div span) { /* our slotted
does not match this */ } ::slotted(div) p { /* can't go inside light DOM */ } ``` Also, `::slotted` can only be used in CSS. We can't use it in `querySelector`. ## CSS hooks with custom properties How do we style a component in-depth from the main document? Naturally, document styles apply to `` element or ``, etc. But how can we affect its internals? For instance, in `` we'd like to allow the outer document change how user fields look. Just as we expose methods to interact with our component, we can expose CSS variables (custom CSS properties) to style it. **Custom CSS properties exist on all levels, both in light and shadow.** For example, in shadow DOM we can use `--user-card-field-color` CSS variable to style fields: ```html
Name:
Birthday:
``` Then, we can declare this property in the outer document for ``: ```css user-card { --user-card-field-color: green; } ``` Custom CSS properties pierce through shadow DOM, they are visible everywhere, so the inner `.field` rule will make use of it. Here's the full example: ```html run autorun="no-epub" untrusted height=80 John Smith 01.01.2001 ``` ## Summary Shadow DOM can include styles, such as `