首页 > 解决方案 > 如何使用 lit html 在 Web 组件中使用 CSS“目标”选择器

问题描述

我正在使用 lit html 在我的项目中创建自定义 Web 组件。我的问题是,当我尝试在 Web 组件中使用 CSS 目标选择器时,它不会被触发,但是当我在没有自定义组件的情况下执行此操作时,代码可以完美运行。有人可以解释为什么会发生这种情况以及解决这个问题的方法是什么?这是我的代码:

目标测试元素.js:

import { LitElement, html} from '@polymer/lit-element';

class TargetTest extends LitElement {

  render(){
    return html`
      <link rel="stylesheet" href="target-test-element.css">
        <div class="target-test" id="target-test">
        <p>Hello from test</p>
    </div>
    `;
  }
}
customElements.define('target-test-element', TargetTest);

具有以下样式:

目标测试元素.css:

.target-test{
    background: yellow;
}

.target-test:target {
    background: blue;
}

我在 index.html 中创建了一个链接:

index.html(带有自定义组件):

<!DOCTYPE html>

<head>
 ...
</head>

<body>
    <target-test-element></target-test-element>
    <a href="#target-test">Link</a>
</body>

</html>

这是有效的:

index.html(没有自定义组件)

<!DOCTYPE html>
<head>
    ...
</head>
<body>
    <a href="#target-test">Link</a>
    <div class="target-test" id="target-test">
        Hello
    </div>
</body>
</html>

标签: javascriptcssweb-componentshadow-domlit-html

解决方案


LitElement 使用 Shadow DOM 来呈现其内容。Shadow DOM 隔离了内部定义的 CSS 样式,并防止使用 CSS 选择器从外部选择内部内容。出于这个原因,:target伪类将不起作用。

相反,您可以使用标准(普通)自定义元素而不是 LitElement。

没有 Shadow DOM:

class TargetTest extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      <div>
        <span class="test" id="target-test">Hello from test</span>
      </div>`
  }
}
customElements.define('target-test-element', TargetTest)
.test { background: yellow } 
.test:target { background: blue }
<target-test-element></target-test-element>
<a href="#target-test">Link</a>

或者,如果您仍想使用 Shadow DOM,则应将该id属性设置为自定义元素本身。假设自定义元素中只有一个目标。

class TargetTest extends HTMLElement {
  connectedCallback() {
    this.attachShadow( { mode: 'open' } ).innerHTML = `
      <style>
        :host( :target ) .test { background-color: lightgreen }
      </style>
      <div>
        <span class="test">Hello from test</span>
      </div>`
  }
}
customElements.define('target-test-element', TargetTest)
<target-test-element id="target-test"></target-test-element>
<a href="#target-test">Link</a>


推荐阅读