Web组件影子DOM中的REM

我们知道可以将font-sizeon[2-1]>设置为正常DOM节点中的rembase,我使用这个技巧使我的应用程序的字体更灵活,随js动态更改。

然而,当我创建一个Web组件时,我发现阴影DOM中的rem总是指向16px,即使我尝试在阴影DOM中添加样式。16px是常见浏览器的默认字体大小。

这里有一个简单的演示: https://jsfiddle.net/qmacwb6r/

<html>
<head>
<script>
var template =`
<style>
* {
    font-size: 72px;
}
div {
    font-size:2rem;
}
</style>
<div>
    I am 2rem = 2*broser default
</div>
`
class TestTemplate extends HTMLElement {
    constructor(){
        super();
        this.rt = this.attachShadow({mode:"open"});
        this.rt.innerHTML = template;
    }
}
customElements.define("test-component", TestTemplate);
</script>
</head>
<body>
<test-component></test-component>
</body>
</html>

我还尝试在控制台中调用getRootNode()

对于普通DOM节点,它返回HTMLElement,而对于阴影DOM节点,它返回ShadowRoot,与HTMLElement不同,它不能设置样式。

是否可以使阴影DOM中节点的rem基本字体可变且可控?


解决方案

除非我遗漏了什么rem值始终基于为<html>标记设置的字体大小:

html {
  font-size: 100px;
}

以上大小1rem等于100px

这里有一个我将htmlfont-size设置为4px的示例。然后在组件中使用rem值。

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
var template = `
<style>
:host, :root { font-size: 48px; }
.rem2 { font-size:2rem; }
.rem3 { font-size:3rem; }
</style>
<p>I am 48px Times</p>
<div class="rem2">I am 2rem = 2*browser default</div>
<div class="rem3">I am 3rem = 3*browser default</div>
`;

class TestTemplate extends HTMLElement {
  constructor(){
    super();
    this.rt = this.attachShadow({mode:"open"});
    this.rt.innerHTML = template;
  }
}
customElements.define("test-component", TestTemplate);
html {
  font: 4px Courier;
}

body {
 font: 24px Tahoma;
}
<div>Before</div>
<test-component></test-component>
<div>After</div>

运行此命令,然后查看DevTools Computed选项卡。您将看到: 1.文本I am 2rem = 2*browser default的字体大小仅为8px 2.文本I am 3rem = 3*browser default的字体大小为12px;

font-size:hostfont-sizerem大小没有任何影响。只有<html>标记中的font-size才有。

相关文章