CSS 在自定义 HTML 元素上无法正常工作

The*_*der 4 html javascript css shadow-dom custom-element

我一直在尝试通过扩展类来创建自定义 HTML 元素HTMLElement。我尝试通过链接与其他两个文件位于同一目录中的 CSS 文件来添加一些样式 -index.htmlcustom.css.

主文件夹

  • 索引.html
  • 自定义.css
  • 自定义.js

index.html:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="nofollow" type="text/css" href=''>
</head>
 
    <body>
        <script src="./custom.js"></script>
        <smooth-button text="Smooth button" no-1 = 1 no-2 = 2></smooth-button>
    </body>
 
</html>
Run Code Online (Sandbox Code Playgroud)

custom.css:

smooth-button{
    display: block;
    color: blue;
    background-color: orange;
}
Run Code Online (Sandbox Code Playgroud)

custom.js:

class SmoothButton extends HTMLElement{
 
    constructor(){
        super();
        this.shadow = this.attachShadow({mode: "open"})
    }
 
    connectedCallback(){
        this.render();
    }
 
    render(){
        this.SumOfNo1AndNo2 = null;
        if(this.getAttribute("no-1")!=null && this.getAttribute("no-2")!=null){
            this.SumOfNo1AndNo2 = parseInt(this.getAttribute("no-1")) + 
            parseInt(this.getAttribute("no-2"));
        }
        else{
            console.log("Invalid attribute.")
        }
        this.shadow.innerHTML = `<button>` + this.getAttribute("text") + " " + this.SumOfNo1AndNo2   
        + "</button>"
    }
 
}
 
customElements.define("smooth-button", SmoothButton);  
Run Code Online (Sandbox Code Playgroud)

这样,我就得到了一个带有文本的按钮,但样式作为一个整体应用于元素,而不是其组成的元素。如何使用外部 CSS 文件将样式分别应用到其每个元素(<button>目前只是一个)?我正在使用外部 CSS,因为当我在这里阅读它时,它在某种程度上更好。

Dan*_*man 6

除了 Brad 和 Emiel 的回答之外,

  • <style>(Brad) 直截了当地在shadowDOM中 添加一个元素
  • (Emilel) 使用级联 CSS 属性
  • 还有更多设置 ShadowDOM 样式的选项:

了解可继承的样式

使用阴影部分

<style>
  ::part(smoothButton){
    display: block;
    color: blue;
    background-color: orange;
  }
</style>

<smooth-button></smooth-button>
<smooth-button></smooth-button>

<script>
  customElements.define("smooth-button", class extends HTMLElement {
    constructor(){
      super()
        .attachShadow({mode:"open"})
        .innerHTML = `<button part="smoothButton">LABEL</button>`;
    }
  });
</script>
Run Code Online (Sandbox Code Playgroud)

但...

你应该问自己的第一个问题:

我真的需要shadowDOM吗?

如果你不想要它的封装行为,那么就不要使用shadowDOM

<style>
  .smoothButton{
    display: block;
    color: blue;
    background-color: orange;
  }
</style>

<smooth-button></smooth-button>
<smooth-button></smooth-button>

<script>
  customElements.define("smooth-button", class extends HTMLElement {
    connectedCallback(){
      this.innerHTML = `<button class="smoothButton">LABEL</button>`;
    }
  });
</script>
Run Code Online (Sandbox Code Playgroud)

影子DOM<slot>

另一种选择是使用 ShadowDOM<slot>元素,因为它们的样式由其容器元素决定

<style>
  .smoothButton{
    display: block;
    color: blue;
    background-color: orange;
  }
</style>

<smooth-button><button class="smoothButton">LABEL</button></smooth-button>
<smooth-button><button class="smoothButton">LABEL</button></smooth-button>

<script>
  customElements.define("smooth-button", class extends HTMLElement {
    constructor(){
      super()
        .attachShadow({mode:"open"})
        .innerHTML = `<slot></slot>`;
    }
  });
</script>
Run Code Online (Sandbox Code Playgroud)

当你深入了解<slot>兔子洞时,请务必阅读这篇(很长)文章:::
slotted CSS 选择器用于在 ShadowDOM 插槽中嵌套子级