:host:defined 不起作用, :host(:defined) 起作用
:host:defined doesn't work, :host(:defined) works
是否不能或不允许合并 :host
and :defined
in CSS, while combining the latter with the :host()
伪类作品?
正如您在下面的示例中看到的,以下
:host:defined { display: block; }
不有效,而
:host(:defined) { display: block; }
有效。
class CustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host { display: none; }
:host:defined { display: block; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
class OtherCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host { display: none; }
:host(:defined) { display: block; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
customElements.define('custom-element', CustomElement);
customElements.define('other-custom-element', OtherCustomElement);
<custom-element></custom-element>
<other-custom-element></other-custom-element>
codepen 上面的代码示例:https://codepen.io/connexo/pen/GRKEGax
从the specification我们可以读到:
The :host
pseudo-class, when evaluated in the context of a shadow tree, matches the shadow tree’s shadow host. In any other context, it matches nothing
The :host()
function pseudo-class has the syntax: :host( <compound-selector-list> )
When evaluated in the context of a shadow tree, it matches the shadow tree’s shadow host if the shadow host, in its normal context, matches the selector argument. In any other context, it matches nothing.
基本上,:host
将匹配影子主机,仅此而已。您不能将它与任何其他 selector 结合使用,而第二种语法允许您在 ()
.
中添加 selector
如果您参考规范中显示的示例:
say you had a component with a shadow tree like the following:
<x-foo class="foo">
<"shadow tree">
<div class="foo">...</div>
</>
</x-foo>
For a stylesheet within the shadow tree:
:host
matches the <x-foo>
element.
x-foo
matches nothing.
.foo
matches only the element.
.foo:host
matches nothing
:host(.foo)
matches the element.
注意 (2) 和 (4)。 (2) selecting 什么都没有,因为没有共同的 selector can select 外影子树。只有 :host
和 :host()
可以做到。 (4) select 什么都没有,因为 :host
被设计为单独用于 select shadow host 但是如果你想添加另一个select或者您必须像 (5) 中那样使用 :host()
。
这里有一个基本的例子来说明:
class CustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host.box { color:red; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
class OtherCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host(.box) { color:red }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
customElements.define('custom-element', CustomElement);
customElements.define('other-custom-element', OtherCustomElement);
<custom-element class="box"></custom-element>
<other-custom-element class="box"></other-custom-element>
现在的问题是:当我们可以简单地将 :host
与任何其他 selector 组合时,为什么我们有两种 selector。
这是为了在解析 selector 时避免混淆和歧义,因为影子主机只能由特殊的 selector 编辑 select。如果我们写 :host.foo
浏览器将尝试将元素与 .foo
和 :host
匹配,但这会很棘手,因为 .foo
只能匹配影子树中的元素,而 :host
可以到外面去解析 selector 来判断是否有 :host
在里面,以便考虑 select 的剩余部分或者匹配影子主机会很乏味。
使用 :host()
让浏览器更容易解析 selector 和 :host
是 :host()
没有 selector 的特例.
Note: This is different from the specificity of similar pseudo-classes, like :matches()
or :not()
, which only take the specificity of their argument. This is because :host
is affirmatively selecting an element all by itself, like a "normal" pseudo-class; it takes a selector argument for syntactic reasons (we can’t say that :host.foo matches but .foo doesn’t), but is otherwise identical to just using :host followed by a selector.
请注意 我们不能说 :host.foo
匹配但 .foo
不匹配
是否不能或不允许合并 :host
and :defined
in CSS, while combining the latter with the :host()
伪类作品?
正如您在下面的示例中看到的,以下
:host:defined { display: block; }
不有效,而
:host(:defined) { display: block; }
有效。
class CustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host { display: none; }
:host:defined { display: block; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
class OtherCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host { display: none; }
:host(:defined) { display: block; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
customElements.define('custom-element', CustomElement);
customElements.define('other-custom-element', OtherCustomElement);
<custom-element></custom-element>
<other-custom-element></other-custom-element>
codepen 上面的代码示例:https://codepen.io/connexo/pen/GRKEGax
从the specification我们可以读到:
The
:host
pseudo-class, when evaluated in the context of a shadow tree, matches the shadow tree’s shadow host. In any other context, it matches nothingThe
:host()
function pseudo-class has the syntax::host( <compound-selector-list> )
When evaluated in the context of a shadow tree, it matches the shadow tree’s shadow host if the shadow host, in its normal context, matches the selector argument. In any other context, it matches nothing.
基本上,:host
将匹配影子主机,仅此而已。您不能将它与任何其他 selector 结合使用,而第二种语法允许您在 ()
.
如果您参考规范中显示的示例:
say you had a component with a shadow tree like the following:
<x-foo class="foo">
<"shadow tree">
<div class="foo">...</div>
</>
</x-foo>
For a stylesheet within the shadow tree:
:host
matches the<x-foo>
element.
x-foo
matches nothing.
.foo
matches only the element.
.foo:host
matches nothing
:host(.foo)
matches the element.
注意 (2) 和 (4)。 (2) selecting 什么都没有,因为没有共同的 selector can select 外影子树。只有 :host
和 :host()
可以做到。 (4) select 什么都没有,因为 :host
被设计为单独用于 select shadow host 但是如果你想添加另一个select或者您必须像 (5) 中那样使用 :host()
。
这里有一个基本的例子来说明:
class CustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host.box { color:red; }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
class OtherCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host(.box) { color:red }
`;
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = `<code><${this.tagName.toLowerCase()}></code> connected!`;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
customElements.define('custom-element', CustomElement);
customElements.define('other-custom-element', OtherCustomElement);
<custom-element class="box"></custom-element>
<other-custom-element class="box"></other-custom-element>
现在的问题是:当我们可以简单地将 :host
与任何其他 selector 组合时,为什么我们有两种 selector。
这是为了在解析 selector 时避免混淆和歧义,因为影子主机只能由特殊的 selector 编辑 select。如果我们写 :host.foo
浏览器将尝试将元素与 .foo
和 :host
匹配,但这会很棘手,因为 .foo
只能匹配影子树中的元素,而 :host
可以到外面去解析 selector 来判断是否有 :host
在里面,以便考虑 select 的剩余部分或者匹配影子主机会很乏味。
使用 :host()
让浏览器更容易解析 selector 和 :host
是 :host()
没有 selector 的特例.
Note: This is different from the specificity of similar pseudo-classes, like
:matches()
or:not()
, which only take the specificity of their argument. This is because:host
is affirmatively selecting an element all by itself, like a "normal" pseudo-class; it takes a selector argument for syntactic reasons (we can’t say that :host.foo matches but .foo doesn’t), but is otherwise identical to just using :host followed by a selector.
请注意 我们不能说 :host.foo
匹配但 .foo
不匹配