【问题标题】:Why does my Web Component CSS not show? I am not using shadowDOM为什么我的 Web 组件 CSS 不显示?我没有使用 shadowDOM
【发布时间】:2018-08-02 21:56:24
【问题描述】:

我有一个未使用 shadowDOM 的 Native V1 组件,因此我将我的 CSS 放在 <head> 中。但是当其他人使用我的组件时,我的 CSS 就不再起作用了。

只有当他们的组件确实使用 shadowDOM 时才会发生这种情况。

我的组件的示例代码:

class MyEl extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div>
    <div class="spaced"><button class="sad-btn">I'm Sad</button></div>`;
  }
}

// Define our web component
customElements.define('my-el', MyEl);
button {
  padding: 8px 20px;
}

.happy-btn {
  background-color: pink;
}

.sad-btn {
  background-color: #007;
  color: white;
}
&lt;my-el&gt;&lt;/my-el&gt;

我的 CSS 被加载到 &lt;head&gt; 标记中,因为我没有使用 shadowDOM。但是一旦外部元素将我包含在他们的 shadowDOM 中,事情就会崩溃。

【问题讨论】:

    标签: css web-component shadow-dom native-web-component


    【解决方案1】:

    如果您正在创建一个不使用 ShadowDOM 的组件,您可能仍需要将 CSS 添加到 shadowRoot 中。如果其他人将您的组件放入他们的 shadowDOM 中,那么您必须将您的 CSS 添加到他们的 shadowRoot 中。您可以使用以下代码执行此操作:

    const myStyle = document.createElement('style');
    myStyle.setAttribute('component', 'my-el');
    myStyle.textContent = `    button {
      padding: 8px 20px;
    }
    .happy-btn {
      background-color: pink;
    }
    
    .sad-btn {
      background-color: #007;
      color: white;
    }`;
    
    function addCss(el, selector, styleEl) {
      // Check to see if we have been placed into a shadow root.
      // If we have then add our CSS into that shadow root.
      let doc;
      try {
        doc = el.getRootNode();
        if (doc === document) {
          doc = document.head;
        }
      }
      catch(_ex) { doc = document.head; } // Shadow DOM isn't supported.
    
      if (!doc.querySelector(selector)) {
        doc.appendChild(styleEl.cloneNode(true));
      }
    }
    
    class MyEl extends HTMLElement {
      constructor() {
        super();
        addCss(this, 'style[component="my-el"]', myStyle);
      }
      connectedCallback() {
        this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div>
        <div class="spaced"><button class="sad-btn">I'm Sad</button></div>`;
      }
    }
    customElements.define('my-el', MyEl);
    
    class TheirEl extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({mode:'open'});
        this.shadowRoot.innerHTML = `<hr/><my-el></my-el><hr/><my-el></my-el><hr/>`;
      }
    }
    customElements.define('their-el', TheirEl);
    &lt;their-el&gt;&lt;/their-el&gt;

    addCss 函数会将您的 CSS 放入正确的 shadowRoot 中,如果没有 shadowRoot,则放入 document.head

    您必须在构造函数中调用 addCss 才能将 CSS 放置在正确的位置。只要您有一个唯一的选择器来识别您的 &lt;style&gt; 标记,此例程还将确保您不会将其添加两次。

    在我的&lt;style&gt; 标签中添加了一个名为component 的属性,其值为组件名称。在我的情况下component="my-el"

    然后我使用选择器'style[component="my-el"]'来查看该标签是否已经在shadowRoot中,如果没有shadowRoot,则使用document.head,如果没有,则仅添加样式已经存在了。

    你不能仅仅因为你没有使用它就认为你的组件不会在 shadow DOM 中。使用上面的示例来保护自己。

    旁注

    如果您使用 shadow DOM,那么这个问题就会消失,因为您必须将 CSS 放入自己的 shadowRoot 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 2016-03-03
      • 1970-01-01
      • 2022-11-16
      • 2017-05-12
      • 2013-05-06
      • 1970-01-01
      相关资源
      最近更新 更多