将全局样式应用于Shadow DOM的正确方法 [英] Correct way to apply global styles into Shadow DOM

查看:527
本文介绍了将全局样式应用于Shadow DOM的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与StackOverflow上的其他问题类似,但是我找不到任何适用于我的情况和非弃用方法的答案(我开始认为这种情况可能没有任何好的解决方案) 。

This questions is similar to some other on StackOverflow, but I couldn't find any answer describing applicable to my situation and non-deprecated method (and I'm starting thinking that maybe there is no any good solution for that situation).

假设我们有一些main.css文件,其中包含按钮,列表,链接等的常用样式。所以它只是一些标准的.css文件,其中包含我们希望在整个应用程序中重用的常见样式。我们希望使用Shadow DOM将相同的样式应用于Web组件。

Let's say we have some main.css file which includes common styles for buttons, lists, links and so on. So it's just some standard .css file which contains common styles that we want to reuse across the application. And we want to apply the same styles to Web Components with Shadow DOM.

我知道有几种方法可以实现这一目标:

There are a few ways, that I know about, to accomplish that:


  1. 使用一种不推荐的方法::: shadow,>>>,/ deep / selectors。但是那些选择器现在已经被弃用了,所以我想这不是一个好的方法来推进。

  2. 使用css变量。如果我们需要设置一些属性,这种方法适用于自定义目的。但是如果我们想从main.css文件迁移10-20个常用样式,那就太复杂了。

  3. 在Shadow DOM中使用@import语句或link标签。它会起作用,但会复制每个组件的所有样式。如果我们有10个Web组件,我们最终会得到10个完全相同样式的重复项。它听起来也不是一个好的解决方案。特别是如果我们有很多常见的样式,从性能的角度来看,这听起来很糟糕。

  4. 根本不使用Shadow DOM并使用全局样式:)但它是不解决当前问题。

  1. Using one of deprecated approaches: ::shadow, >>>, /deep/ selectors. But those selectors are deprecated by now, so I guess it's not good approach to move forward with.
  2. Using css variables. This approach is good for customization purposes, if we need to set a few properties. But it's too complex if we want to migrate 10-20 common styles from main.css file.
  3. Using @import statement or "link" tags inside of Shadow DOM. It will work, but it will duplicate all styles for every component. If we have 10 web components we will end up with 10 duplicates of exactly the same styles. It doesn't sound like good enough solution too. Especially if we have a lot of common styles, sounds like it can be bad solution from performance point of view.
  4. Don't use Shadow DOM at all and use global styles :) But it's not solution for current problem.

我还检查了Angular Framework中是如何解决同一问题的(我检查了Angular的第5版)。当我将封装行为设置为Native时,它实际上只是复制样式(如上面描述的#3),我认为这不是最好的方式(但可能是目前最好的方式)。

I also checked how the same problem resolved in Angular Framework (I checked version 5 of Angular). When I set encapsulation behavior to Native, it's just actually duplicating styles (like in #3 described above), what I think isn't the best way (but maybe the best currently existing way).

那么,有没有人知道在没有上述缺点的情况下是否有其他方法可以解决这个问题?听起来像Shadow DOM的当前缺点带来了比它试图解决的更多问题。

So, does anyone know if there is any other way to solve this problem without described above drawbacks? It just sounds like current drawbacks of Shadow DOM bring even more problems than it tries to solve.

推荐答案

解决方案3没有真正的缺点:

There's no real drawback with solution 3:


  1. 无论是将CSS样式应用于主文档中的n个元素,还是应用于n Shadow DOM中的1个元素,样式都将复制到整个n个元素。

  1. Whether you apply a CSS style to n elements in a main document, or to 1 element in n Shadow DOM, the style will be duplicated to the whole n elements anyways.

如果您在n Shadow DOM中导入文档n次,则实际上只会加载一次,并通过浏览器缓存重复使用。

If you import a document n times in n Shadow DOM, il will be actually be loaded only one time and reused through the browser cache.

之后,il将依赖Shadow DOM和CSS样式的浏览器实现,你应该看到只有数千个Shadow DOM的性能下降。

After that, il will rely on the browser implementation of Shadow DOM and CSS styles, and you should see a performance degradation only the thousands of Shadow DOM.

对于Chrome 73+和Opera 60 +的2019更新

现在你可以直接实现 CSSStyleSheet 对象并将其分配给不同的Shadow DOM。

Now you can directly instanciate a CSSStyleSheet object and assign it to different Shadow DOMs.

这个HTML不会重复的方式。

This way the HTML won't be duplicated.

var css = new CSSStyleSheet()
css.replaceSync( "@import url( main.css )" )
host.shadowRoot.adoptedStyleSheets = [css] 
host2.shadowRoot.adoptedStyleSheets = [css] 

您还可以将其应用于全球文档:

You can also apply it to the global document:

document.adpotedStyleSheets = [css]

另一个优点是样式表上的更新将应用于所有Shadow采用它的DOM(和文档)。

The other advantage is that an update on the stylesheet will be applied to all Shadow DOMs (and document) that adopted it.

 css.replaceSync( '.color { color: red }' )

这篇关于将全局样式应用于Shadow DOM的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆