为什么我们更喜欢CSS自定义属性而不是SASS变量

2020-07-08 06:09:44

自从我们的框架在几个月前发布以来,许多用户问我们为什么选择CSS变量,而不是sass变量,尽管我们在框架中使用了sass。在本文中,我将介绍使用自定义属性的优点,以及为什么它们在我们的工作流程中变得至关重要。

在本文中,我假设您熟悉CSS自定义属性和sass(或任何其他CSS预处理器)的基础知识。如果你不是,让我们从一个基本的例子开始:

原生的自定义属性允许您定义变量,而不需要CSS扩展(即SASS)。

它们是一样的吗?不怎么有意思!。与sass变量不同,自定义属性1)的作用域是声明它们的元素,2)级联,3)可以在JavaScript中操作。这三个特点开启了一个全新的可能性世界。让我给你看一些实际的例子!

以下是如何使用sass变量创建两个(简化)颜色主题的示例:

$COLOR-PRIMARY:蓝色;$COLOR-TEXT:黑色;$COLOR-BG:白色;/*INVERT*/$COLOR-PRIMARY-INVERT:红色;$COLOR-TEXT-INVERT:白色;$COLOR-BG-INVERT:黑色;.component{COLOR:$COLOR-TEXY;}}.component--暗{COLOR:$COLOR-TEXT-INVERT;BACKGROUND:$COLOR-BG-INVERT;a。

在上面的示例中,我们有一个默认主题和一个深色主题,在该主题中我们反转了背景和文本的颜色。请注意,在黑暗主题中,我们需要检查使用颜色变量的每个属性,并使用新变量更新它们。

只要我们坚持使用简化的(不现实的)示例,就不会出现问题。如果我们有一个包含大量元素的组件呢?我们将再次被迫重写使用颜色变量的所有属性,并替换变量。如果你改变了主成分,你必须仔细检查所有的修改器。所以是的.不是很方便!

在构建我们的框架时,我们提出了一种基于CSS变量的不同方法。首先,让我们定义颜色变量:

:root,[Data-Theme=";默认";]{--color-primary:蓝色;/*颜色对比度*/-color-bg:白色;--color-对比度-LOWER:HSL(0,0%,95%);--COLOR-对比度-LOW:HSL(240,1%,83%);--COLOR-对比度中等:HSL(240,1%,48%);--COLOR-对比度高:HSL(240,4%,20。--COLOR-对比度-高:黑色;}[数据-主题]{背景色:vAR(--COLOR-BG);COLOR:vAR(--COLOR-对比度-高);}[数据-主题=";暗";]{--COLOR-PRIMARY:红色;/*COLOR对比度*/-COLOR-BG:黑色;--COLOR-COLRATION-LOWER:HSL(240,6%,15%);--颜色对比度低:HSL(252%,4%,25%);--颜色对比度介质:HSL(240,1%,57%);--颜色对比度高:HSL(0,0%,89%);--颜色对比度高:白色;}。

仅供参考:在上面的示例中,我们使用data-*属性来应用颜色主题,但这与CSS变量和sass变量无关。此外,我们使用基于对比度级别的命名法定义了中性值的标度。

重要的一点是,我们不需要为第二个(暗)主题创建新的颜色变量。与sass不同,我们可以覆盖现有自定义属性的值。

.component{color:var(--color-对比度-Higher);背景色:var(--color-bg);边框-下:1px实心var(--color-对比度-低);a{color:var(--color-primary);}}。

那部件的暗色变化呢?我们不需要额外的CSS。因为我们要覆盖而不是替换变量,所以我们只需要在第一次创建组件时应用正确的颜色变量。不管组件变得多么复杂,一旦您在_color s.scss文件中设置了颜色主题,并将颜色变量应用于组件的元素,您就可以用一种非常简单的方式应用颜色主题:

在上面的示例中,我们已将暗主题应用于部分,并将默认颜色主题应用于.Child元素。没错,你可以嵌套颜色主题!

这项技术通过使用CSS自定义属性而成为可能,它使您可以立即完成像这样很酷的事情。👇

如果您想了解有关如何使用CodyHouse框架管理颜色的更多信息,以下是一些链接:

文字(或模块化)比例是应用于排版元素的一组和谐(大小)值。以下是如何使用sass变量在SCSS中设置文字比例:

标准方法是使用第三方工具(或计算)创建文字比例,然后将值导入到您的样式中,如上例所示。

在构建我们的框架时,我们决定将整个比例公式合并到自定义样式/_typography.scss文件中。下面是我们如何使用CSS变量设置文字比例:

:root{//正文字体大小--text-base-size:1em;//type scale--text-scale-rate:1.2;--text-xs:calc((1em/var(--text-scale-rate)/var(--text-scale-rate));--text-sm:calc(var(--text-xs)*var(--text-scale-rate));--text-md:calc(var(--text-sm)*var(--text-scale-rate)*var(--text-scale-rate));--text-lg:calc(var(--text-md)*var(--text-scale-rate));--text-xl:calc(var(--text-lg)*var(--text-scale-rate));--text-XXL:Calc(var(--text-xl)*var(--text-scale-rate));--text-XXXL:calc(var(--text-xxl)*var(--text-scale-rate));}。

这种方法的好处是什么?它使您可以通过只编辑两个变量来控制整个排版系统:--text-base-size(正文字体大小)和--text-scale-rate(比例乘数)。

可以,但是您不能使用sass变量做同样的事情吗?否,如果要修改特定断点处的排版:

上面的代码片段是我们响应方法的基石。因为我们使用EMS相对单位,所以当修改--text-base-size(正文字体大小)时,字体和间距都会受到影响。您最终得到的系统可以调整所有组件的大小,几乎不需要在组件级别设置媒体查询。

间距比例等同于文字比例,但适用于间隔值。再一次,将比例公式包含到框架中使我们能够控制间距系统并使其具有响应性:

:root{--space-unit:1em;--space-xxxs:calc(0.125*var(--space-unit));--space-xxs:calc(0.25*var(--space-unit));--space-xxs:calc(0.375*var(--space-unit));--space-xs:calc(0.375*var(--space-unit));--space-sm:calc(0.75*。--space-md:calc(1.25*var(--space-unit));--space-lg:calc(2*var(--space-unit));--space-xl:calc(3.25*var(--space-unit));--space-XXL:calc(5.25*var(--space-unit));--space-XXXL:calc(8.5*var(--space-unit));--space-XXXXL:Calc(13.75*var(--space-unit));}@Supports(--css:Variables){:root{@include断点(Md){--space-unit:1.25em;}。

当与上一章中讨论的排版方法结合使用时,这种方法会变得特别强大。只需几行CSS,您就可以得到响应组件:

我喜欢将EMS单位与此间距系统一起使用的一点是,如果间距和字体大小在特定断点处显示正确,那么几乎可以肯定它们在所有断点处都显示正确,而不管您更新--space-unit值的事实如何。由此推论,我可以在几乎不需要调整浏览器窗口大小的情况下进行设计(除非我想要更改组件的行为);而且当我确实要调整窗口大小时,间距和版式也可以很好地调整。

与sass变量不同,我们可以覆盖CSS变量的值。利用此功能的一种方法是将自定义属性注入到其他自定义属性中,从而创建可在组件级别上编辑的控件。

下面是一个示例:当您设置文本组件的垂直间距时,您可能希望为元素指定行高和页边距:

.文章{h1,h2,h3,h4{行高:1.2;页边距-底部:$SPACE-Xs;}ul,ol,p,块引用{行高:1.5;页边距-底部:$SPACE-Md;}}。

但是,此间距根据文本使用位置的不同而不同。例如,如果希望文本更加紧凑,则需要创建组件变体,在其中应用不同的间隔值:

.文章--sm{h1,h2,h3,h4{line-Height:1.1;March-Bottom:$SPACE-XXXS;}ul,ol,p,BLOCK QUOQUE{LINE-HEIGHT:1.4;LENGE-BOOT:$SPACE-sm;}}。

.text-component{--component-body-line-high:Calc(var(--body-line-high)*var(--line-high-multiier,1));--component-heading-line-high:Calc(var(--heading-line-high)*var(--line-high-multiier,1));--line-high-multiier:1;--text-vspace-multiier:1;h1,h2,h3,h4{。空边距-底部:Calc(var(--space-XXXS)*var(--text-vSpace-Multiier));}h2,h3,h4{空边-顶部:Calc(var(--space-sm)*var(--text-vSpace-Multiier));}p,块报价,ul li,ol li{line-high:var(--component-body-line-high);}ul,ol,p,块引用,.text-component__block,.text-component__img{空格-底部:calc(var(--space-sm)*var(--text-vspace-multiier));}}。

行高度乘数和--text-vspace-multiier是文本组件的两个作用域控件。当我们创建.text-component类的修饰符时,要编辑垂直间距,我们只需要覆盖这两个变量:

.protle.text-component{//如博客帖子--line-高度-乘数:1.13;//增加文章行高--text-vspace-乘数:1.2;//增加垂直间距}。

可以通过多种方式使用覆盖组件值的可能性。通常,只要您可以将组件的行为抽象为一个或多个变量,当该组件需要编辑时(或者您必须创建该组件的变体),您的工作就会变得更轻松。

我们的Auto Size Grid组件就是一个例子,在该组件中,我们使用CSS网格创建布局,其中库项目根据CSS中设置的最小宽度自动填充可用空间,然后我们提取项目的最小宽度值,并将其存储在变量中。

设置图库项目的最小宽度,让我们的gridAuto Mixin为您完成繁重的工作https://t.co/IPkjDHGCSD😉pic.twitter.com/yfFijBffEv。

-CodyHouse(@CodyWebHouse)2019年3月7日

在创建自动调整网格大小组件的变体时,该最小宽度值是唯一需要修改的内容。

简而言之:浏览器支持。不过,等一下!您可以在PostCSS插件的帮助下以本文描述的所有方式使用CSS自定义属性。您可以做的事情有一些限制,一些更改(例如,编辑垂直节奏)仅适用于现代浏览器。在这些特定情况下,只要不破坏旧浏览器的体验,您就可以自由使用CSS变量。有关当前使用CSS变量的限制的更多信息,请查看我们的文档。

是!。只要Sass(或任何其他预处理器)允许您做在CSS中做不到的事情,而且您需要这些东西,为什么不使用它呢?Sass不是用户在访问您的网站时必须下载的库。它是您工作流程中的一个工具。例如,我们使用sass来定义使用CSS变量的颜色函数。

在本文中,我们已经通过了几个示例来演示使用CSS自定义属性比使用sass变量的优势是什么。我们将重点放在它们如何使您能够创建控件,以加快您修改组件或设置影响排版和间距的规则的速度。我们已经涉及了很多领域,我希望你能从这篇文章中学到一些东西,并把它融入到你的工作中。😊。

你想分享一下你是如何使用CSS变量的,还是对这篇文章有反馈意见?在推特上联系吧!