编译非根 CSS 自定义属性

Posted

技术标签:

【中文标题】编译非根 CSS 自定义属性【英文标题】:Compile non-root CSS custom property 【发布时间】:2017-03-26 12:19:27 【问题描述】:

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

.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;

目标是

通过在根 DOM 元素上切换暗/亮类来切换配色方案 使用有效的 css 语法(无 sass 少) 保持规则代码紧凑

【问题讨论】:

“编译”是什么意思?您是在谈论将自定义属性转换为它们的非自定义属性等价物吗?您的自定义道具示例已按预期工作。 我希望转译器/预处理器将“自定义属性转换为其非自定义属性等效项” 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

次优解决方案。 一些 CSS 可以transpiled 以实现更好的浏览器支持。但是,我找到的解决方案是在非:root 元素上使用not support 变量。还有other objections 反对将“未来”CSS 转换为“当前”CSS。据我所知,如果您想转译不在:root 元素上的自定义属性,则必须实现自己的转译器(或postcss 插件),但请注意is hard 通常。现在你不需要通用部分,所以它是可能的。只是,据我所知,还不存在。

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

现在你说以下,

使用有效的 css 语法(没有更少的 sass)

但无论如何我都会展示这一点,因为我相信它是解决您问题的有效方法。如果您想/需要支持 IE、Edge 和/或其他主要浏览器的旧版本(Firefox

您可以使用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;

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

保持规则代码紧凑

但是您在此处所说的(我认为)是您希望将自定义属性从它们的规则中分离出来以节省规则的数量,这不是我所知道的任何预处理器所支持的。

您可以将源 SASS 组织在单独的文件中,以便轻松进行概览。您甚至可以设置一个构建系统,为您拥有的每个主题生成单独的样式表。然后可以让您的用户选择alternative stylesheet。浏览器对此有一些支持,但在后一种情况下也绝对可以使用 javascript 进行切换。只需将所有样式表设置为disabled,所选样式表除外。 Here is an example.

【讨论】:

但是你的代码是倒置的,不等于我的例子。如果添加新的 .block1 .block2 类,那么我需要更改 mixin 定义,这不是我想要的。我想声明深色和浅色并在 .block 规则中使用它们 @exe-dealer 我认为我所拥有的与您的示例相同。无论如何,我大量编辑了我的答案,希望能澄清很多。希望这会有所帮助。

以上是关于编译非根 CSS 自定义属性的主要内容,如果未能解决你的问题,请参考以下文章

通过 JavaScript 访问 CSS 自定义属性(又名 CSS 变量)

css自定义属性—css变量

将自定义形状应用于剪辑属性 CSS

使用负 CSS 自定义属性 [重复]

CSS中 自定义属性(变量)详解

CSS中 自定义属性(变量)详解