编译非 root CSS 自定义 属性

Compile non-root CSS custom property

是否有任何工具可以编译 CSS 在 not :root 规则下声明的自定义属性?我想要以下带有自定义属性的代码

.dark {
  --bg-color: black;
  --fg-color: white;
}

.light {
  --bg-color: white;
  --fg-color: black;
}

.foo {
  background: var(--bg-color);
  display: block;
}

.bar {
  color: var(--fg-color);
  display: inline;
}

像这样编译成它们的非自定义道具等价物

.light .foo, .light.foo {
  background: white;
}

.dark .foo, .dark.foo {
  background: black;
}

.light .bar, .light.bar {
  color: black;
}

.dark .bar, .dark.bar {
  color: white;
}

.foo {
  display: block;
}

.bar {
  display: inline;
}

目标是

理想的解决方案。你的例子是有效的CSS和can be used in many browsers(不在IE、Edge(但正在开发中)和Opera Mini中写这个答案,2017-03-27,其他主流浏览器都可以。

次优解。有些CSS一般可以transpiled to achieve better browser support. The solution I found does not support variables on non-:root elements, however. There are also other objections against transpiling of 'future' CSS into 'current' CSS. To the best of my knowledge, you will have to implement your own transpiler (or postcss plugin) if you want to transpile custom properties not on the :root element, but be warned that that is hard。现在你不需要通用部分,所以这是可能的。据我所知,只是还不存在。

预处理解决方案。当然,您不需要自定义属性的通用实现。您有不同的主题,这些主题对同一组属性具有自己的值,仅此而已。因此,可以使用任何 CSS 预处理器创建单独的样式表作为预处理步骤。

现在你说下面的话,

use valid css syntax (no sass less)

但无论如何我都会展示它,因为我相信它是解决您的问题的有效方法。如果您希望 to/need 支持 IE、Edge and/or 其他主要浏览器的旧版本(Firefox < 31、Chrome < 49、Safari < 9.1, 歌剧 < 36)

例如,您可以使用 SASS 在服务器端进行转译。

// define styles, use variables throughout them
// your entire style definition goes into this mixin
@mixin myStyles($fg-color, $bg-color) {
  .foo {
    display: block;
    background: $bg-color;
  }

  .bar {
    display: inline;
    color: $fg-color;
  }
}

// define themes, that set variables for the above styles
// use named arguments for clarity
.dark {
  @include myStyles(
    $fg-color: white,
    $bg-color: black
  );
}

.light {
  @include myStyles(
    $fg-color: black,
    $bg-color: white
  );
}

编译为以下内容。

.dark .foo {
  display: block;
  background: black;
}
.dark .bar {
  display: inline;
  color: white;
}

.light .foo {
  display: block;
  background: white;
}
.light .bar {
  display: inline;
  color: black;
}

这不完全是你想要得到的,但非常接近。实际上,我认为这是您最接近获得所需输出的时间。我知道你想

keep rules code compact

但是你在那里说的(我认为)是你想从他们的规则中分离出自定义属性以节省规则数量,这不是我所知道的任何预处理器支持的东西。

您可以将源代码 SASS 组织在单独的文件中,以便轻松地保持概览。您甚至可以设置一个构建系统,为您拥有的每个主题生成单独的样式表。然后可以让您的用户 select 和 alternative stylesheet. Browsers have some support for this, but switching using JavaScript is also definitely possible in the latter case. Simply set all stylesheets to be disabled except for the selected one. Here is an example.

这样做实际上并不安全。我可以告诉你,因为我非常努力地进行安全转换。 但是我失败了。

https://github.com/postcss/postcss-custom-properties/issues/1