为什么宿主元素上的伪类必须在宿主函数内部?

Why do pseudoclasses on the host element have to be inside of the host function?

我不明白为什么像:focus-within这样的伪类在作用于主机本身时需要在:host()函数括号内。为什么不能是:host:focus-within div? 更奇怪的是它在另一个 :host().

:host 上工作

class MyElementFail extends HTMLElement {

 constructor(...args) {
  super(...args)

  this.attachShadow({mode: 'open'}).innerHTML = `
  <style>
    :host{
      display: block;
      padding: 20px;
      background-color: salmon;
    }
    :host div{
      background-color: white;
    }
    /*This part is different:*/
  :host:focus-within div{
   background-color: green;
  }
  </style>
    <input type="text" value="click in here"/>
  <div>
    Change to green
  </div>`
 }
}
window.customElements.define('my-element-fail', MyElementFail);


class MyElement extends HTMLElement {

 constructor(...args) {
  super(...args)

  this.attachShadow({mode: 'open'}).innerHTML = `
  <style>
    :host{
      display: block;
      padding: 20px;
      background-color: salmon;
    }
    :host div{
      background-color: white;
    }
    /*This part is different:*/
  :host(my-element:focus-within) div{
   background-color: green;
  }
  </style>
    <input type="text" value="click in here"/>
  <div>
    Change to green
  </div>`
 }
}
window.customElements.define('my-element', MyElement);


class MyElementTwo extends HTMLElement {

 constructor(...args) {
  super(...args)

  this.attachShadow({mode: 'open'}).innerHTML = `
  <style>
    :host{
      display: block;
      padding: 20px;
      background-color: salmon;
    }
    :host div{
      background-color: white;
    }
    /*This part is different:*/
  :host(:host:focus-within) div{
   background-color: green;
  }
  </style>
    <input type="text" value="click in here"/>
  <div>
    Change to green
  </div>`
 }
}
window.customElements.define('my-element-two', MyElementTwo);
No Good:
<my-element-fail></my-element-fail>
Good:
<my-element></my-element>
Good also:
<my-element-two></my-element-two>

本质上,为什么,

:host(:host:focus-within) div{ 工作,

:host(my-element:focus-within) div{ 有效,但是

:host:focus-within div{ 不行吗?

:host只是表示shadowDOM的宿主元素。

:host(.something)表示主机class为.something

你不能使用:host.something你必须使用括号。

:host() 不是函数。这就是如何 select 具有额外特异性的 :host

class MyElement extends HTMLElement {
 constructor() {
  super();
  this.attachShadow({mode: 'open'}).innerHTML = `
  <style>
    :host{
      display: block;
      padding: 20px;
      background-color: salmon;
    }

    div{
      background-color: white;
    }

    :host(:focus-within) div{
   background-color: green;
  }
  </style>
    <input type="text" value="click in here"/>
  <div>Change to green</div>`;
 }
}
window.customElements.define('my-element', MyElement);
<my-element></my-element>

其实原因在Selector Level 4 specification:

The shadow host in a shadow tree is featureless and therefore cannot be matched by any pseudo-class except for :host [...].

示例中的 hyperlink 对此进行了说明(实际上还有您在评论中指向 @Intervalia 的回答的 link)。

转换为您的用例:

:focus-within 与影子主机不匹配。因此,:host:focus-within 更具体地说,should/could 不匹配任何内容(这与 CSS 选择基本原则相矛盾)。

因此 :host() 函数伪 class 将模仿其他选择器但不会破坏它们的逻辑。