minor
This commit is contained in:
parent
4a8d8987df
commit
8319c71e03
1 changed files with 15 additions and 14 deletions
|
@ -1,6 +1,6 @@
|
||||||
# Shadow DOM styling
|
# Shadow DOM styling
|
||||||
|
|
||||||
Shadow DOM may include both `<style>` and `<link rel="stylesheet" href="…">` tags. In the latter case, stylesheets are HTTP-cached, so they are not redownloaded. There's no overhead in @importing or linking same styles for many components.
|
Shadow DOM may include both `<style>` and `<link rel="stylesheet" href="…">` tags. In the latter case, stylesheets are HTTP-cached, so they are not redownloaded for multiple components that use same template.
|
||||||
|
|
||||||
As a general rule, local styles work only inside the shadow tree, and document styles work outside of it. But there are few exceptions.
|
As a general rule, local styles work only inside the shadow tree, and document styles work outside of it. But there are few exceptions.
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ customElements.define('custom-dialog', class extends HTMLElement {
|
||||||
|
|
||||||
## Cascading
|
## Cascading
|
||||||
|
|
||||||
The shadow host (`<custom-dialog>` itself) resides in the light DOM, so it's affected by the main CSS cascade.
|
The shadow host (`<custom-dialog>` itself) resides in the light DOM, so it's affected by document CSS rules.
|
||||||
|
|
||||||
If there's a property styled both in `:host` locally, and in the document, then the document style takes precedence.
|
If there's a property styled both in `:host` locally, and in the document, then the document style takes precedence.
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ custom-dialog {
|
||||||
```
|
```
|
||||||
...Then the `<custom-dialog>` would be without padding.
|
...Then the `<custom-dialog>` 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.
|
It's very convenient, as we can setup "default" component styles in its `: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.
|
The exception is when a local property is labelled `!important`, for such properties, local styles take precedence.
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ For example, we'd like to center the `<custom-dialog>` only if it has `centered`
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
|
border-color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
@ -108,13 +109,13 @@ customElements.define('custom-dialog', class extends HTMLElement {
|
||||||
</custom-dialog>
|
</custom-dialog>
|
||||||
```
|
```
|
||||||
|
|
||||||
Now the additional centering styles are only applied to the first dialog `<custom-dialog centered>`.
|
Now the additional centering styles are only applied to the first dialog: `<custom-dialog centered>`.
|
||||||
|
|
||||||
## :host-context(selector)
|
## :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`.
|
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 `<custom-dialog>` on above it:
|
E.g. `:host-context(.dark-theme)` matches only if there's `dark-theme` class on `<custom-dialog>` on anywhere above it:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<body class="dark-theme">
|
<body class="dark-theme">
|
||||||
|
@ -190,11 +191,11 @@ customElements.define('user-card', class extends HTMLElement {
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Here `<p>John Smith</p>` becomes bold, because CSS inheritance is in effect between the `<slot>` and its contents. But not all CSS properties are inherited.
|
Here `<p>John Smith</p>` becomes bold, because CSS inheritance is in effect between the `<slot>` and its contents. But in CSS itself not all properties are inherited.
|
||||||
|
|
||||||
Another option is to use `::slotted(selector)` pseudo-class. It matches elements based on two conditions:
|
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 `<slot>`. Then slot name doesn't matter. Just any slotted element, but only the element itself, not its children.
|
1. That's a slotted element, that comes from the light DOM. Slot name doesn't matter. Just any slotted element, but only the element itself, not its children.
|
||||||
2. The element matches the `selector`.
|
2. The element matches the `selector`.
|
||||||
|
|
||||||
In our example, `::slotted(div)` selects exactly `<div slot="username">`, but not its children:
|
In our example, `::slotted(div)` selects exactly `<div slot="username">`, but not its children:
|
||||||
|
@ -239,21 +240,21 @@ Also, `::slotted` can only be used in CSS. We can't use it in `querySelector`.
|
||||||
|
|
||||||
## CSS hooks with custom properties
|
## CSS hooks with custom properties
|
||||||
|
|
||||||
How do we style a component in-depth from the main document?
|
How do we style internal elements of a component from the main document?
|
||||||
|
|
||||||
Naturally, document styles apply to `<custom-dialog>` element or `<user-card>`, etc. But how can we affect its internals? For instance, in `<user-card>` we'd like to allow the outer document change how user fields look.
|
Selectors like `:host` apply rules to `<custom-dialog>` element or `<user-card>`, but how to style shadow DOM elements inside them?
|
||||||
|
|
||||||
Just as we expose methods to interact with our component, we can expose CSS variables (custom CSS properties) to style it.
|
There's no selector that can directly affect shadow DOM styles from the document. But 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.**
|
**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:
|
For example, in shadow DOM we can use `--user-card-field-color` CSS variable to style fields, and the outer document can set its value:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<style>
|
<style>
|
||||||
.field {
|
.field {
|
||||||
color: var(--user-card-field-color, black);
|
color: var(--user-card-field-color, black);
|
||||||
/* if --user-card-field-color is not defined, use black */
|
/* if --user-card-field-color is not defined, use black color */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="field">Name: <slot name="username"></slot></div>
|
<div class="field">Name: <slot name="username"></slot></div>
|
||||||
|
@ -321,8 +322,8 @@ Local styles can affect:
|
||||||
- slotted elements (coming from light DOM), `::slotted(selector)` allows to select slotted elements themselves, but not their children.
|
- slotted elements (coming from light DOM), `::slotted(selector)` allows to select slotted elements themselves, but not their children.
|
||||||
|
|
||||||
Document styles can affect:
|
Document styles can affect:
|
||||||
- shadow host (as it's in the outer document)
|
- shadow host (as it lives in the outer document)
|
||||||
- slotted elements and their contents (as it's physically in the outer document)
|
- slotted elements and their contents (as that's also in the outer document)
|
||||||
|
|
||||||
When CSS properties conflict, normally document styles have precedence, unless the property is labelled as `!important`. Then local styles have precedence.
|
When CSS properties conflict, normally document styles have precedence, unless the property is labelled as `!important`. Then local styles have precedence.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue