可以使用`<style>`标签从shadow DOM中导入字体吗?

问题描述 投票:0回答:2

可以从 Shadow dom 中导入字体并将其应用于其子项吗?

当尝试做类似的事情时

class MyCustomElement extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.innerHTML = `
      <style>
        @import url('https://fonts.googleapis.com/css?family=Open+Sans');
        :host {
          font-family: 'Open Sans';
        }
      </style>
      <h1>Hello font?</h1>
    `;
  }
}
customElements.define('my-custom-element', MyCustomElement);

字体未应用于

<h1>
。 CSS 检查器显示
<h1>
的字体计算为
"Open Sans"
。在网络选项卡中,Chrome 请求样式表,但 Firefox 不请求。在这两种浏览器中,它都以系统默认字体呈现。

要完成这项工作还缺少什么?

完整的 HTML 文件是,

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Font test</title>
  </head>
  <body>
    <script>
      class MyCustomElement extends HTMLElement {
        constructor() {
          super();
          const shadowRoot = this.attachShadow({ mode: "open" });
          shadowRoot.innerHTML = `
      <style>
        @import url('https://fonts.googleapis.com/css?family=Open+Sans');
        :host {
          font-family: 'Open Sans';
        }
      </style>
      <h1>Hello font?</h1>
    `;
        }
      }
      customElements.define("my-custom-element", MyCustomElement);
    </script>
    <my-custom-element></my-custom-element>
  </body>
</html>

火狐

css fonts shadow-dom
2个回答
0
投票

当您在 Shadow DOM 中使用“@import”时,由于应用样式的时间安排,它并不总是按预期工作。 在您的情况下,“@import”规则可能无法及时应用于字体系列声明。

class MyCustomElement extends HTMLElement {
      constructor() {
       super();
       const link = document.createElement('link');
       link.rel = 'stylesheet';
       link.href = 'https://fonts.googleapis.com/css?family=Open+Sans';
       document.head.appendChild(link);
       const shadowRoot = this.attachShadow({mode: 'open'});
                    shadowRoot.innerHTML = `
                      <style>
                        :host {
                          font-family: 'Open Sans', sans-serif;
                        }
                      </style>
                      <h1>Hello font?</h1>
                    `;
                  }
                }
  customElements.define('my-custom-element', MyCustomElement);

0
投票

您必须在全局范围和 Web 组件中注册外部字体

<script>
customElements.define('my-element', class extends HTMLElement {
  constructor() {
  
    let href = "https://fonts.googleapis.com/css?family=Open+Sans";

    super().attachShadow({mode:'open'})
           .innerHTML = `<style>@import url('${href}')</style>` +
           `<style>:host{font-family:'Open Sans'}</style>` + 
           `<h1>Hello Font: </h1>`;

    // make sure font is globally loaded
    let fontExist = 
        //document.fonts.check("32px Open Sans");
        document.querySelector(`link[href="${href}"]`);
    if (!fontExist) {
      console.log("append LINK font");
      document.head.append(
        Object.assign(document.createElement("link"), {
          rel: "stylesheet",
          href,
          onload : () => this.fontloaded()
        }))
    } else {
      this.fontloaded();
    } 
  }

  fontloaded(){
    let h1 = this.shadowRoot.querySelector("h1");
    h1.innerHTML += getComputedStyle(h1).font;
    this.hidden = false;
    console.log(document.fonts.check('0px Open Sans'));
  }
});
</script>
<my-element hidden></my-element>

© www.soinside.com 2019 - 2024. All rights reserved.