- Notifications
You must be signed in to change notification settings - Fork1.2k
Shadow DOM styling#739
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
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
23 commits Select commitHold shift + click to select a range
e418449 Add translation of 8-web-components/6-shadow-dom-style/article.md
wen-k-s3e7b9d2 Add translation of 8-web-components/6-shadow-dom-style/article.md
wen-k-sad9c963 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s88e95bc Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sdb4e34c Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s938f902 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sa6d0189 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-se98e51a Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s82c3189 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s8a84b24 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s77e3575 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sc26c0fe Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s05e1783 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s46dbb41 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s9a1d9c1 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sbd68c53 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s03a8996 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s7799d78 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s425872b Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s36b77dc Update 8-web-components/6-shadow-dom-style/article.md
wen-k-s178481a Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sf167f34 Update 8-web-components/6-shadow-dom-style/article.md
wen-k-sf391464 Update 8-web-components/6-shadow-dom-style/article.md
MartinsYongFile 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
127 changes: 64 additions & 63 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 @@ | ||
| #给Shadow DOM添加样式 | ||
| shadow DOM可以包含`<style>`和 `<link rel="stylesheet" href="…">`标签。在后一种情况下,样式表是HTTP 缓存的,因此不会为使用同一模板的多个组件重新下载样式表。 | ||
| 一般来说,局部样式只在 shadow 树内起作用,文档样式在shadow树外起作用。但也有少数例外。 | ||
| ## :host | ||
| `:host`选择器允许选择shadow宿主(包含shadow树的元素)。 | ||
| 例如,我们正在创建`<custom-dialog>`元素,并且想使它居中。为此,我们需要对`<custom-dialog>`元素本身设置样式。 | ||
| 这正是`:host`所能做的: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <template id="tmpl"> | ||
| <style> | ||
| /*这些样式将从内部应用到custom-dialog元素上 */ | ||
| :host { | ||
| position: fixed; | ||
| left: 50%; | ||
| @@ -42,32 +42,33 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
| </custom-dialog> | ||
| ``` | ||
| ##级联 | ||
| shadow宿主(`<custom-dialog>`本身)驻留在light DOM 中,因此它受到文档CSS规则的影响。 | ||
| 如果在局部的 `:host` 和文档中都给一个属性设置样式,那么文档样式优先。 | ||
| 例如,如果在文档中我们有如下样式: | ||
| ```html | ||
| <style> | ||
| custom-dialog { | ||
| padding: 0; | ||
| } | ||
| </style> | ||
| ``` | ||
| ……那么`<custom-dialog>`将没有padding。 | ||
| 这是非常有利的,因为我们可以在其`:host`规则中设置 “默认” 组件样式,然后在文档中轻松地覆盖它们。 | ||
| 唯一的例外是当局部属性被标记`!important` 时,对于这样的属性,局部样式优先。 | ||
| ## :host(selector) | ||
| 与`:host` 相同,但仅在shadow宿主与`selector` 匹配时才应用样式。 | ||
| 例如,我们希望仅当`<custom-dialog>`具有`centered`属性时才将其居中: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <template id="tmpl"> | ||
| @@ -109,32 +110,33 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
| </custom-dialog> | ||
| ``` | ||
| 现在附加的居中样式只应用于第一个对话框:`<custom-dialog centered>`。 | ||
| ## :host-context(selector) | ||
| 与`:host` 相同,但仅当外部文档中的shadow宿主或它的任何祖先节点与`selector` 匹配时才应用样式。 | ||
| 例如,`:host-context(.dark-theme)`只有在 `<custom-dialog>` 或者`<custom-dialog>`的任何祖先节点上有 `dark-theme` 类时才匹配: | ||
| ```html | ||
| <body class="dark-theme"> | ||
| <!-- | ||
| :host-context(.dark-theme)只应用于.dark-theme 内部的 custom-dialog | ||
| --> | ||
| <custom-dialog>...</custom-dialog> | ||
| </body> | ||
| ``` | ||
| 总之,我们可以使用 `:host`-family 系列的选择器来对组件的主元素进行样式设置,具体取决于上下文。这些样式(除 `!important` 外)可以被文档样式覆盖。 | ||
| ## 给占槽( slotted )内容添加样式 | ||
| 现在让我们考虑有插槽的情况。 | ||
| 占槽元素来自 light DOM,所以它们使用文档样式。局部样式不会影响占槽内容。 | ||
wen-k-s marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| 在下面的例子中,按照文档样式,占槽的 `<span>` 是粗体,但是它不从局部样式中获取 `background`: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <style> | ||
| *!* | ||
| @@ -163,11 +165,11 @@ customElements.define('user-card', class extends HTMLElement { | ||
| </script> | ||
| ``` | ||
| 结果是粗体,但不是红色。 | ||
| 如果我们想要在我们的组件中设置占槽元素的样式,有两种选择。 | ||
| 首先,我们可以对`<slot>`本身进行样式化,并借助CSS继承: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <user-card> | ||
| @@ -191,14 +193,14 @@ customElements.define('user-card', class extends HTMLElement { | ||
| </script> | ||
| ``` | ||
| 这里 `<p>John Smith</p>`变成粗体,因为CSS继承在`<slot>`和它的内容之间有效。但是在CSS中,并不是所有的属性都是继承的。 | ||
| 另一个选项是使用`::slotted(selector)`伪类。它根据两个条件来匹配元素: | ||
| 1.这是一个占槽元素,来自于light DOM。插槽名并不重要,任何占槽元素都可以,但只能是元素本身,而不是它的子元素 。 | ||
| 2.该元素与`selector` 匹配。 | ||
| 在我们的例子中,`::slotted(div)`正好选择了`<div slot="username">` ,但是没有选择它的子元素: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <user-card> | ||
| @@ -224,55 +226,55 @@ customElements.define('user-card', class extends HTMLElement { | ||
| </script> | ||
| ``` | ||
| 请注意,`::slotted`选择器不能用于任何插槽中更深层的内容。下面这些选择器是无效的: | ||
| ```css | ||
| ::slotted(div span) { | ||
| /*我们插入的<div>不会匹配这个选择器 */ | ||
| } | ||
| ::slotted(div) p { | ||
| /*不能进入light DOM 中选择元素 */ | ||
| } | ||
| ``` | ||
| 此外,`::sloated` 只能在CSS 中使用,不能在`querySelector` 中使用。 | ||
| ##用自定义CSS属性作为勾子 | ||
| 如何在主文档中设置组件的内建元素的样式? | ||
| 像`:host`这样的选择器应用规则到`<custom-dialog>`元素或`<user-card>`,但是如何设置在它们内部的shadow DOM元素的样式呢? | ||
| 没有选择器可以从文档中直接影响shadow DOM样式。但是,正如我们暴露用来与组件交互的方法那样,我们也可以暴露CSS变量(自定义CSS属性)来对其进行样式设置。 | ||
| **自定义 CSS属性存在于所有层次,包括lightDOM 和shadow DOM。** | ||
| 例如,在shadow DOM中,我们可以使用`--user-card-field-color` CSS变量来设置字段的样式,而外部文档可以设置它的值: | ||
| ```html | ||
| <style> | ||
| .field { | ||
| color: var(--user-card-field-color, black); | ||
| /*如果 --user-card-field-color没有被声明过,则取值为black */ | ||
| } | ||
| </style> | ||
| <div class="field">Name: <slot name="username"></slot></div> | ||
| <div class="field">Birthday: <slot name="birthday"></slot></div> | ||
| </style> | ||
| ``` | ||
| 然后,我们可以在外部文档中为`<user-card>` 声明此属性: | ||
| ```css | ||
| user-card { | ||
| --user-card-field-color: green; | ||
| } | ||
| ``` | ||
| 自定义 CSS属性穿透shadow DOM,它们在任何地方都可见,因此内部的`.field`规则将使用它。 | ||
| 以下是完整的示例: | ||
| ```html run autorun="no-epub" untrusted height=80 | ||
| <style> | ||
| @@ -310,26 +312,25 @@ customElements.define('user-card', class extends HTMLElement { | ||
| </user-card> | ||
| ``` | ||
| ## 小结 | ||
| shadow DOM 可以引入样式,如 `<style>` 或 `<link rel="stylesheet">`。 | ||
| 局部样式可以影响: | ||
| - shadow 树, | ||
| - shadow 宿主(通过 `:host`-family 系列伪类), | ||
| - 占槽元素(来自 light DOM),`::slotted(selector)` 允许选择占槽元素本身,但不能选择它们的子元素。 | ||
| 文档样式可以影响: | ||
| - shadow宿主(因为它位于外部文档中) | ||
| -占槽元素及占槽元素的内容(因为它们同样位于外部文档中) | ||
| 当 CSS属性冲突时,通常文档样式具有优先级,除非属性被标记为`!important`,那么局部样式优先。 | ||
| CSS自定义属性穿透shadow DOM。它们被用作 “勾子” 来设计组件的样式: | ||
| 1.组件使用自定义CSS属性对关键元素进行样式设置,比如`var(--component-name-title, <default value>)` 。 | ||
| 2.组件作者为开发人员发布这些属性,它们和其他公共的组件方法一样重要。 | ||
| 3.当开发人员想要对一个标题进行样式设计时,他们会为 shadow 宿主或宿主上层的元素赋值`--component-name-title` CSS属性。 | ||
| 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.