- Notifications
You must be signed in to change notification settings - Fork179
Shadow DOM styling#418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
dolgachio merged 2 commits intojavascript-tutorial:masterfromSamGreenberg:shadow-dom-stylingDec 8, 2022
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
2 commits Select commitHold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
140 changes: 70 additions & 70 deletions8-web-components/6-shadow-dom-style/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,21 @@ | ||
#Стилізація тіньового DOM | ||
Тіньовий DOMможе включати в себе обидва теги`<style>`та `<link rel="stylesheet" href="…">`. В останньому випадку, таблиці стилів зберігаються в кешіHTTP, тому вони не завантажуються наново для кількох компонентів, які використовують один і той самий шаблон. | ||
Як правило, локальні стилі працюють лише всередині тіньового дерева та стилі документу працюють ззовні. Але є декілька винятків. | ||
## :host | ||
Селектор `:host`дозволяє обрати тіньовий хост (елемент, що містить в собі тіньове дерево). | ||
Наприклад, ми створюємо елемент`<custom-dialog>`, який має бути центрованим. Для цього нам треба стилізувати безпосередньо елемент `<custom-dialog>`. | ||
Саме це робить `:host`: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<template id="tmpl"> | ||
<style> | ||
/*стилі буде застосовано зсередини до елементуcustom-dialog */ | ||
:host { | ||
position: fixed; | ||
left: 50%; | ||
@@ -38,36 +38,36 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
</script> | ||
<custom-dialog> | ||
Привіт! | ||
</custom-dialog> | ||
``` | ||
##Каскад | ||
Тіньовий хост (безпосередньо`<custom-dialog>`) розташований в світломуDOM,тому на нього впливаютьCSS-правила документу. | ||
Якщо властивість задана як локально через`:host`, так і глобально в документі, пріоритет мають стилі документу. | ||
Наприклад, якщо в документі ми маємо: | ||
```html | ||
<style> | ||
custom-dialog { | ||
padding: 0; | ||
} | ||
</style> | ||
``` | ||
...Тоді`<custom-dialog>`не матиме відступів. | ||
Це дуже зручно, оскільки ми можемо встановити типові стилі компоненту локально всередині його`:host`правила, та легко перетерти їх стилями документу. | ||
Винятком є ситуація, коли локальна властивість позначена як`!important`,для таких властивостей, пріоритет надається локальним стилям. | ||
## :host(selector) | ||
Теж саме, що й`:host`,але застосовується лише у випадку, коли тіньовий хост співпадає з `selector`. | ||
Наприклад, ми бажаємо центрувати`<custom-dialog>`, тільки якщо він має атрибут`centered`: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<template id="tmpl"> | ||
@@ -101,25 +101,25 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
<custom-dialog centered> | ||
Центровано! | ||
</custom-dialog> | ||
<custom-dialog> | ||
Не центровано. | ||
</custom-dialog> | ||
``` | ||
Тепер додаткові стилі центрування застосовуються лише до першого діалогу: `<custom-dialog centered>`. | ||
Підсумовуючи, ми можемо використовувати сімейство селекторів`:host` для стилізації основного елементу компоненту. Ці стилі (окрім позначених як`!important`)можуть бути перевизначені глобальними стилями документу. | ||
##Стилізація контенту слотів | ||
Розглянемо ситуацію зі слотами. | ||
Елементи слотів приходять зі світлого DOM,тому вони використовують стилі документу. Локальні стилі не впливають на вміст слотів. | ||
У наведеному нижче прикладі,`<span>`має жирний шрифт, згідно стилю документу, але не приймає`background`з локального стилю: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<style> | ||
*!* | ||
@@ -128,7 +128,7 @@ In the example below, slotted `<span>` is bold, as per document style, but does | ||
</style> | ||
<user-card> | ||
<div slot="username">*!*<span>Петро Щур</span>*/!*</div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. 👍 | ||
</user-card> | ||
<script> | ||
@@ -148,15 +148,15 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
Результат має жирний шрифт, але не червоний фон. | ||
Якщо б ми забажали стилізувати елементи в нашому компоненті, ми б мали два варіанти. | ||
Перший: стилізувати конкретно`<slot>`та розраховувати наCSSуспадкування: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<user-card> | ||
<div slot="username">*!*<span>Петро Щур</span>*/!*</div> | ||
</user-card> | ||
<script> | ||
@@ -176,19 +176,19 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
В даному випадку,`<p>Петро Щур</p>`має жирний шрифт, оскільки CSSуспадкування діє між`<slot>`та його наповненням. Але в самомуCSSне всі властивості успадковуються. | ||
Другою опцією є використання псевдо-класу `::slotted(selector)`. Він застосовує стилі відповідно до двох умов: | ||
1.Це елемент-слот, що приходить зі світлогоDOM.Назва слоту не має значення. Будь-який слот, але саме цей елемент, а не його діти. | ||
2.Елемент збігається з `selector`. | ||
В нашому прикладі, `::slotted(div)`застосовується саме до`<div slot="username">`,без дочірніх елементів: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<user-card> | ||
<div slot="username"> | ||
<div>Петро Щур</div> | ||
</div> | ||
</user-card> | ||
@@ -209,54 +209,54 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
Зверніть увагу, селектор`::slotted`не може спускатися вниз структурою слоту. Такі селектори є невалідними: | ||
```css | ||
::slotted(div span) { | ||
/*наш<div>з цим не збігається */ | ||
} | ||
::slotted(div) p { | ||
/*не може потрапити всередину світлого DOM */ | ||
} | ||
``` | ||
Також, `::slotted`може використовуватись лише вCSS.Ми не можемо ним користуватись в `querySelector`. | ||
## CSSхуки з кастомними властивостями | ||
Як ми можемо стилізувати внутрішні елементи компоненту з основного документу? | ||
Селектори по типу`:host`застосовують правила до елементу`<custom-dialog>`чи`<user-card>`,але як стилізувати елементи тіньового DOMвсередині нього? | ||
Жоден селектор не може напряму вплинути на стилі тіньовогоDOMз глобальних стилів документу. Але так само, як ми надали доступ до методів, щоб взаємодіяти з нашим компонентом, ми можемо відкрити CSSзмінні(кастомні CSSвластивості) для його стилізації. | ||
**Кастомні CSSвластивості існують на всіх рівнях, як в світловому, так і в тіньовому.** | ||
Наприклад, в тіньовому DOMми можемо використовувати CSS змінну`--user-card-field-color`для стилізації полів, а зовнішній документ може призначати їй значення: | ||
```html | ||
<style> | ||
.field { | ||
color: var(--user-card-field-color, black); | ||
/*якщо --user-card-field-colorне призначено, використовуємо чорний колір */ | ||
} | ||
</style> | ||
<div class="field">Ім’я: <slot name="username"></slot></div> | ||
<div class="field">День народження: <slot name="birthday"></slot></div> | ||
``` | ||
Після того, ми можемо оголосити цю властивість в зовнішньому документі для `<user-card>`: | ||
```css | ||
user-card { | ||
--user-card-field-color: green; | ||
} | ||
``` | ||
Кастомні CSSвластивості пронизують тіньовийDOM,вони є видимими усюди, тож внутрішнє правило `.field`їх використає. | ||
Нижче наведений повний приклад: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<style> | ||
@@ -275,8 +275,8 @@ Here's the full example: | ||
} | ||
*/!* | ||
</style> | ||
<div class="field">Ім’я: <slot name="username"></slot></div> | ||
<div class="field">День народження: <slot name="birthday"></slot></div> | ||
</template> | ||
<script> | ||
@@ -289,31 +289,31 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
<user-card> | ||
<span slot="username">Петро Щур</span> | ||
<span slot="birthday">01.01.2001</span> | ||
</user-card> | ||
``` | ||
##Підсумки | ||
Тіньовий DOMможе включати в себе стилі, як то `<style>`чи `<link rel="stylesheet">`. | ||
Локальні стилі можуть впливати на: | ||
-тіньове дерево, | ||
-тіньовий хост з псевдокласами`:host`та `:host()`, | ||
-елементи-слоти (які приходять зі світлогоDOM), `::slotted(selector)`дозволяє обрати лише їх, без дочірніх елементів. | ||
Стилі документу можуть впливати на: | ||
-тіньовий хост (через його перебування в зовнішньому документі) | ||
-елементи-слоти та їх вміст (також через перебування в зовнішньому DOM документа) | ||
Коли CSSвластивості суперечать одна одній, зазвичай стилі документу мають перевагу, якщо дана властивість не позначена як `!important`.Тоді перевага надається локальним стилям. | ||
CSSкастомні властивості пронизують тіньовийDOM.Вони використовуються в якості хуків, аби стилізувати компонент: | ||
1.Компонент використовує кастомнуCSSвластивість задля стилізації ключових елементів, таких як `var(--component-name-title, <default value>)`. | ||
2.Автор компоненту робить ці властивості публічними для розробників, вони так само важливі як й інші публічні методи компоненту. | ||
3.Коли розробник хоче стилізувати заголовок, вони присвоюють CSS властивість`--component-name-title`тіньовому хосту або рівню вище. | ||
4.Профіт! |
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.