首页 > 解决方案 > 在 Web 组件中使用外部 CSS 链接引用

问题描述

我正在尝试在自定义 Web 组件中使用 CDN 中的 Bulma,但它似乎不起作用。

我的 html 有这个:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>hello</title>
  <meta charset="utf-8">
</head>
<body>
    <my-element></my-element>
    <script src="index.js"></script>

</body>
</html>

这对于我的 js 文件:

const sheet = new CSSStyleSheet()

sheet.replace('@import url("https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css")');

class MyElement extends HTMLElement {
    connectedCallback(){
        let that = this
        let id = Math.random()
        this.id = id

        const shadowRoot = this.attachShadow({ mode: 'open' })
        shadowRoot.adoptedStyleSheets = [sheet]

        let child = document.createElement('button')
        child.classList.add("button")
        child.innerText = id

        child.id = count

        shadowRoot.appendChild(child)

        this.addEventListener('click', e => {
            e.target
            console.log(that.id)
            that.remove()
        })
    }
}

if(!customElements.get('my-element')){
    customElements.define('my-element', MyElement)
}

let count = Math.floor(Math.random() * 10) + 1
for(i = 0; i <= count; i++){
    let el = document.createElement('my-element')
    document.body.appendChild(el)
}

值得注意的是,如果我使用sheet.replaceSync('button { color: green; }')而不是sheet.replace(...),它可以正常工作。但是为什么外部 CSS 链接引用导入不起作用?

更新:我意识到我在控制台中收到以下警告:

index.js:6 @import rules are not allowed here. See https://github.com/WICG/construct-stylesheets/issues/119#issuecomment-588352418.

作为说明,我正在尝试使用这种方法,因此我可以以相同的方式设置多个自定义 Web 组件的样式,而无需多次导入样式表。

谢谢!

标签: javascriptcssweb-component

解决方案


我的方法是为所有组件使用单个实例,如下所示:

import bulmaStyles from 'https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css';
const bulmaCSS = new CSSStyleSheet;
bulmaCSS.replaceSync(bulmaStyles);

export class Styles {
  static get bulma() { return bulmaCSS }
}

然后,在您的组件中,导入此类

import { Styles } from 'path/to/Styles.js';

class MyElement extends HTMLElement {
    constructor() {
      super();
      // and use it in the constructor after creating the shadow DOM
      this.attachShadow({ mode: 'open' })
      this.shadowRoot.adoptedStylesheets = [ Styles.bulma ];
    }
}

为了能够import将样式表的 CSS 转换为变量,您需要构建堆栈来支持它。Webpack 支持它,例如在webpack-raw-loader.

如果你不打包你的代码,你将不得不等待 CSS 模块,或者从 DOM 中获取样式。


推荐阅读