【问题标题】:Why do pseudoclasses on the host element have to be inside of the host function?为什么宿主元素上的伪类必须在宿主函数内部?
【发布时间】:2019-07-15 20:14:07
【问题描述】:

我不明白为什么像: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{ 不工作?

【问题讨论】:

标签: css html web-component shadow-dom custom-element


【解决方案1】:

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

:host(.something).something 的类指示主机。

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

:host() 不是函数。这只是如何选择具有额外特异性的: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);
&lt;my-element&gt;&lt;/my-element&gt;

【讨论】:

  • 我认为这是一个很好的解释,但规范说:host() 一个函数。 drafts.csswg.org/css-scoping/#host-selector
  • 不知道他们为什么使用function这个词,因为它与:not()devdocs.io/css/:not的风格基本相同。 CSS 确实有像 calc() and var()` 这样的真正函数,但 :host() 只是一个伪类
  • 也许他们想说的是 functional 而不是 function
  • 也许吧。或者:not() 现在被认为是一个函数,这只是伪类使用括号时使用的术语。 :)
  • 您的报价来自哪里?引用时请不要忘记提供出处!
【解决方案2】:

其实原因在Selector Level 4 specification中给出:

影子树中的影子主机是无特征的,因此除了:host [...] 之外的任何伪类都无法匹配。

示例中的hyperlink 对此进行了说明(实际上也是您在评论中指向@Intervalia 答案的链接)。

转换为您的用例:

:focus-within 与影子主机不匹配。所以,:host:focus-within 更具体,应该/不能匹配任何东西(这与 CSS 选择基础相矛盾)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2019-05-28
    • 2014-10-09
    • 1970-01-01
    • 2016-10-19
    相关资源
    最近更新 更多