External font does not load when link is loaded from inside the shadowDOM
Asked Answered
G

1

8

At the begining I want to say that I'm aware that the question is similar to:

How to let imported css font / icons have effects on elements in the shadow dom?

It's not the case and it does not help.

Issue: I've recently decided to use the ShadowDOM to encapsulate the styles in my project. At the very begining it I thought it worked as expected but I've noticed that some of the icons coming from the external CSS files were gone. It's important to notice that those styles are external and possibilities of making changes are limited.

I've prepared the code to demonstrate the issue (look at the snippet below).

Everything seems to be working fine except the @font-face

As You can see, HTML containing the external CSS file with icons works as expected outside the ShadowDOM. I'd like to use it inside the shadowDOM as well.

How can I achieve that ?

NOTE: If you check the dev tools, there is a problem with the CSS path in network tab but it's the SO snippet issue. If You run the snippet locally, everything is ok in network.

const body = document.getElementsByTagName('body')[0];
const wrapper = document.querySelector('.wrapper')

const handleAddToShadowClick = (param) => {
  const host = document.querySelector('#shadowHost');
  if(param === 'insideShadow') {
    const shadowRoot = host.attachShadow({mode: 'open'});
     shadowRoot.innerHTML = firstComponent
  } else {
    const shadowRoot = host;
    wrapper !== null ? body.removeChild(wrapper): '' 
    shadowRoot.innerHTML = firstComponent
  }
}

const firstComponent = `
<div class="wrapper">
  <div class="icon login">Bla bla</div>
  <div style="font-family: testFont;">Sample String od text</div>
  <link rel="stylesheet" href="./style.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
</div>  
`
.wrapper {
    font-family: agGridBalham;
    background-color: aquamarine;
    color: black;
}

.balham:before {
    content: "\F11F";
}

.login::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900; 
    content: "\f007";
  }
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
      Refresh the page after each button click
    </p>
    <button onclick="handleAddToShadowClick('outside')">Add outside shadow</button>
    <button onclick="handleAddToShadowClick('insideShadow')">Add inside shadow</button>  
<div>
  <div id="shadowHost"> </div> 
</div>
    
    <script src="./script.js"></script>
  </body>
</html>
Granduncle answered 1/6, 2020 at 9:25 Comment(1)
Actually it is really a duplicate of the link you quoted. And the solution proposed in the answer you accepted is the same. See also https://mcmap.net/q/1328497/-chrome-extension-shadow-dom-import-boostrap-fontsAxle
B
9

The behavior mentioned in the question is a bug which has been there in chromium(It was also there in Gecko too not sure if it has been fixed or not).

Here is the link for the bug reported at chromium related to this issue, which still not resolved by them. At, present i feel this is the only workaround which will work.

The issue is mainly related to scoping of @font-face. Currently you cannot use the fonts awesome fonts when they are only included inside the shadow DOM. So inorder to use the fonts the fonts css must be present inside both light DOM and shadow DOM. So you need to import the font css both inside the shadow dom and the light dom.

Here is a Working Plunker which solves your problem.

<html>
  <head>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
  </head>

  <body>
      Refresh the page after each button click
    </p>
    <button onclick="handleAddToShadowClick('outside')">Add outside shadow</button>
    <button onclick="handleAddToShadowClick('insideShadow')">Add inside shadow</button>  
    <div>
      <div id="shadowHost"> </div> 
    </div>
    <script src="lib/script.js"></script>
  </body>
</html>

As you can see the plunker above, we have included the font-awesome css both in light DOM and Shadow Dom. And it is working fine as intended.

Bron answered 2/6, 2020 at 8:2 Comment(2)
Thank You very much for Your help :) Basically using a light dom is something I wanted to avoid. Is there a possibility to use the font only inside the shadow dom without including it in the light dom? If not - do You have any resource or articles that could help me understand it from the technological perspective ?Granduncle
@Granduncle I have updated the answer. It is a bug reported in chromium and is still not resolved. You can have a look thanks.Bron

© 2022 - 2024 — McMap. All rights reserved.