如何动态创建可被早期规则覆盖的 css 样式规则

How to dynamically create a css style rule that is overridable by earlier rules

我一直在我的项目中使用jss来做动态样式。这在大多数情况下都非常有效,但我想做一些似乎无济于事的事情。

我希望能够先创建一组主要样式规则,然后创建一组默认样式规则,如果它们发生冲突,这些默认样式规则可以被主要样式规则覆盖。示例:

<div class="mainClass1 defaultClass1">text</div>
<script>
jss.set('.mainClass1', {
  color: 'red'
})

jss.set('.defaultClass1', {
  color: 'green'
})
</script>

我希望结果是文本是红色的,但是jss的运行方式,文本是绿色的。我希望我能以某种方式创建两个动态样式 sheet,第一个是 "default" sheet,第二个是 "main" sheet(以便主要覆盖默认)。这可能吗?

更新 - 我确认了一种适用于原始 javascript:

的技术
var styleNode = document.createElement('style');
styleNode.type = 'text/css';
styleNode.rel = 'stylesheet';
document.head.appendChild(styleNode);
//styleNode.sheet.insertRule("#A" + ' { color:green; }', 1);

var styleNode2 = document.createElement('style');
styleNode2.type = 'text/css';
styleNode2.rel = 'stylesheet';
document.head.appendChild(styleNode2);
styleNode2.sheet.insertRule("#A" + ' { color:green; }', 0);
styleNode.sheet.insertRule("#A" + ' { color:red; }', 0);

即使在较早的样式sheet 上添加红色样式后,id 为'A' 的元素仍保持绿色。现在我只是想知道我是否可以用 jss 来做这个,或者我是否需要自己做一些事情。

为什么这不起作用?

var jss1 = jss.forDocument(document)
var jss2 = jss.forDocument(document)

jss2.set('#A', {
    color: 'green'
})
jss1.set('#A', {
    color: 'red'
})

使用 CSS 选择器

您可以非常简单地做到这一点,只需使用多个 classes 选择器:

jss.set('.defaultClass1.mainClass1', {...});

这比 .defaultClass 选择器具有更高的 class 特异性。


使用 JSS 扩展插件

JSS plugin 简化了扩展样式。例如,您可以这样做(从存储库中的示例复制。

var button0 = {
    padding: '20px',
    background: 'blue'
}

var redButton = {
    background: 'red'
}

window.styles = {
    button0: button0,
    button1: {
        extend: [button0, redButton],
        'font-size': '20px'
    }
}

这会将 button0button1 样式注册到当前 window(就像链接 CSS 文件一样)。

对 jss 源代码的简要检查使我相信您的答案在于创建不同的样式表。从我的简短阅读看来,后来创建的样式表中的 CSS 覆盖了先前创建的样式表中的 CSS。

"Read the source"

好吧,我想出了如何用 jss 做到这一点:

<div id="a">A div</div>
<script>
    var jss1 = jss.forDocument(document)
    jss1.defaultSheet = jss1._createSheet()
    var jss2 = jss.forDocument(document)
    jss2.defaultSheet = jss2._createSheet()

    jss2.set('#A', {
        color: 'green'
    })
    jss1.set('#A', {
        color: 'red'
    })
</script>

我发现 jss 懒惰地创建了它的 sheet。所以如果你想保证stylesheet的顺序,你需要先用_createSheet创建它们。