关于 css:如何包含 Chrome 扩展内容脚本的样式?

How can I contain the styles of a Chrome Extension content script?

我正在开发一个将一些 UI 反应组件注入页面的 Chrome 扩展程序。

UI 组件来自 react-mdl。使用它们需要我在项目顶部包含一个 css 文件。

不幸的是,一旦将 css 注入页面,整个页面的字体就会改变。

有没有办法限制 react-mdl 使用的 css 的范围,这样它就不会影响我要注入的页面?


将这个作为已接受的答案发布给后人值得称赞,但如果有人发现自己处于类似的困境中,以下是对我有用的代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// my injected code
window.addEventListener('load', () => {
    const injectDiv = document.createElement('div')
    const shadowRoot = injectDiv.attachShadow({ mode: 'open' })

    // note inline use of webpack raw-loader, so that the css
    // file gets inserted as raw text, instead of attached to <head>
    // as with the webpack style-loader

    shadowRoot.innerHTML = // just using template string
      `
       <style>${require('raw-loader!app/styles/extension-material.css')}</style>
       
       `
    document.body.appendChild(injectDiv)
    ReactDOM.render(
          <App />,
          // note you have to start your query in the shadow DOM
          // in order to find your root
          shadowRoot.querySelector('#shadowReactRoot')
        )
})

那么,果然:

shadow


我认为你应该使用 Shadow DOM API。当您只需要将 UI 组件附加到网页时,这是一种很好的做法。

https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom


正如在另一篇 SO 帖子中提到的,也支持 <link> 标签,因此可以简单地执行以下操作:

1
2
3
4
5
6
7
const injectedDiv = document.createElement('div');
const shadowRoot = injectedDiv.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `\\
   <link rel="stylesheet" type="text/css" href="${chrome.extension.getURL("bootstrap.min.css")}"></link>\\
   <link rel="stylesheet" type="text/css" href="${chrome.extension.getURL("whatever.css")}"></link>\\
`;
document.body.appendChild(injectedDiv);

注释:

  • 获取扩展的本地资源 url 需要使用 chrome.extension.getURL,参见例如在这个答案中。
  • 链接的 .css 资源必须在 manifest.jsonweb_accessible_resources 属性下声明(否则,您将收到此错误)