专栏名称: 众成翻译
翻译,求知的另一种表达
目录
相关文章推荐
人民日报  ·  别沾边!再萌也不要碰!国家卫健委紧急提醒 ·  12 小时前  
新华社  ·  票房破200亿! ·  昨天  
南都周刊  ·  何小鹏,重磅官宣! ·  昨天  
51好读  ›  专栏  ›  众成翻译

从sass到PostCSS

众成翻译  · 掘金  ·  · 2021-01-29 19:19

正文

阅读 15

从sass到PostCSS

译者:Icarus

原文链接:https://tylergaw.com/articles/sass-to-postcss 译者:Icarus
邮箱:[email protected]

多年来我一直使用Sass.但是最近我想要使用PostCSS和它的cssnext插件来尝试处理样式.我爱死了现在就可以使用将来的CSS特性,相对于之前我用的工具,它们更顺手一些.我的个人站点就是尝试新特性的最好的测试地.

第一步是列出我Sass用法的清单.我需要知道我使用了哪些特性,并且确信新特性在postCSS中有替代品.以下是我正在这个项目中使用的特性:

  • 部分引用(partial import)

  • 变量(variables)

  • 嵌套(nesting)

  • 混合宏(mixins)

  • 拓展(extend)

  • 占位类(placeholder classes)

  • 颜色函数(darken and rgba color functions)

  • 压缩(compression)

准备工作

在切换到新语法之后我需要做一些准备.现在项目的目录结构是Sass的典型用法.我用下划线( _ )来命名文件,文件的拓展名为 scss .我使用两个文件夹来组织Sass文件. moudules 文件夹保存不直接产生CSS的Sass文件,像是变量、占位类和混合宏. partials 保存编译出CSS的Sass文件.

这是最初的文件结构:

css/
  scss/
    modules/
      _module.scss
      ...
    partials/
      _partial.scss
      ...
    tylergaw.scss

复制代码

每个Sass组件会在 tylergaw.scss 中引入.

@import ""modules/setup"";
@import ""modules/reset"";
@import ""modules/fonts"";

复制代码

我重新组织并且重命名了文件.我先把所有文件的后缀名从 scss 改为 css .我使用了一个Bash脚本来完成这项工作,而不是一个一个修改.

`for f in *.scss; do git mv -- ""$f"" ""${f%.scss}.css""; done;`

复制代码

前面的下划线是编写Sass的习惯所以我也去掉了它.我没办法使用Bash命令一次性完成,所以只能手动每个去修改.

最后一步就是将所有的CSS文件都移动至 modules 文件夹并且删除 partials 文件夹.我认为将所有CSS都当成modules来管理要比将他们按照moudules/partials拆分更容易理解.

环境搭建

我以 PostCSS CLI 为起始,在 package.json 里添加了一个临时的构建脚本命令:

""scripts"": {
  ""postcss"": ""postcss -o public/css/tylergaw.css src/css/tylergaw.css""
}

复制代码

在没有更改任何样式的情况下我编译了CSS:

`npm run postcss`

复制代码

正常工作.控制台没有报错,但是页面上没有任何CSS样式.

A screenshot of tylergaw.com missing all styles

构建过程是可用的,现在的任务是把样式找回来.

在Chrome的控制台里我看到了很多404信息.这表示我们第一个丢失的特性就是内联 @import . tylergaw.css 通过 @import 来引入CSS模块.浏览器看到这些,知道它要做什么.浏览器会通过HTTP请求来加载每个模块.我的构建过程只复制了一个独立的CSS文件,而不是每个模块.正因如此,浏览器找不到它们.

我可以改变构建过程来让默认的 @import 工作,但那样效率很低.我需要一个Sass样式内联 @import 的替代品.

第一个插件

postcss-import 插件可以代替Sass中的 @import ,在通过npm安装之后,我更新了构建脚本代码:

""scripts"": {
  ""postcss"": ""postcss -u postcss-import -o public/css/tylergaw.css src/css/tylergaw.css""
}

复制代码

再次运行 npm run postcss ,单个的CSS文件就包含了所有模块.现在的页面就展示出了部分样式. A screenshot of tylergaw.com with partial styles

这会是CSS的未来吗?

在Sass中展现出内联方式的 @import 功能是非常强大的.它让我们能更好的组织样式.我不确定将来这个功能会不会原生支持.我们使用这种功能时总是需要一步编译,看起来也不坏.

我想 postcss-import 插件会成为我PostCSS的一个主要配置,对其他人来说应该也一样.下面引用了插件作者的看法:

This plugin should probably be used as the first plugin of your list. This way, other plugins will work on the AST as if there were only a single file to process, and will probably work as you can expect.

[postcss-import](https://github.com/postcss/postcss-import#postcss-import)

复制代码

cssnext

cssnext 是PostCSS中一个插件,用于将未来CSS特性编译为现今支持的特性.特别需要指出,它和Sass或Less并非不同的语言.它提供正在进行中的CSS规范的特性.一些特性已经得到浏览器支持.另外一些还处于规范的初始阶段.

我使用cssnext来填补失去的Sass特性留下的鸿沟.

浏览器私有前缀

在构建这个网站之前我了解过 Autoprefixer .我用 自定义Sass混合宏 来解决添加所需要的前缀的问题.cssnext包含了Autoprefixer,所以我可以将这整个混合宏模块移除.

变量

下一步我将Sass变量改为CSS自定义属性.比如在 _setup.scss 中,我这样写:

$grey: #1e1e1d;
$yellow: #ffad15;
$offwhite: #f8f8f8;
$darkerwhite: darken($offwhite, 15);

复制代码

这不是所有我使用的Sass变量,但是主要就这些.剩下都在独立的模块中.

注意: 自定义属性和变量的区别.CSS自定义属性只在属性值有效,不能用于选择器,属性名或媒体查询.

新的 setup.css :

:root {
  --white: #fff;
  --grey: #1e1e1d;
  --yellow: #ffad15;
  --offwhite: #f8f8f8;
  ...
}

复制代码

以下为使用示例:

a {
  color: var(--yellow);
}

复制代码

除了语法,CSS自定义属性和Sass变量工作方式是相同的.由于浏览器支持的限制,自定义属性值仍然需要编译.在上面的示例中,编译后的值为 color: #ffad15 .

颜色函数

在之前的例子中,我遗漏了一个变量: $darkerwhite: darken($offwhite, 15); .这是另一个我需要寻找替代的Sass特性.这里有一个 规范草案 提供CSS颜色函数.cssnex现在包含这些函数,这非常酷.下面是 setup.css ,其中 darkerwhite 自定义属性是通过颜色函数和阴影调节器来实现的.

:root {
  ...
  --offwhite: #f8f8f8;
  --darkerwhite: color(var(--offwhite) shade(20%));
  ...
}

复制代码

颜色函数提供了许多 调节器 .你可以在一个函数中使用多个调节器:

`background-color: color(#d32c3f shade(40%) alpha(40%));`

复制代码

编译结果为:

`background-color: rgba(127, 26, 38, 0.4);`

复制代码

再次重申,现在cssnext会将 color() 编译为16进制或rgba的色值.当颜色函数得到浏览器支持后,编译过程就没有必要了.颜色操作在运行时就可以发生.

嵌套

嵌套是CSS预处理器不可或缺的特性.任何让人舒服的样式工具的必需品.Tab Atkins对CSS嵌套有一个正在进行中的 规范 ,并且cssnext让它成为现实.

CSS的嵌套语法包含一个前置于内层的 & ,以下为sass片段:

.projects-list {
  ...

  li {
    & > div {...}
  }

  a {
    ...

    &:hover,
    &:focus {...}

    &::after {...}
  }

  @media (min-width: 640px) {...}
}

复制代码

对于CSS嵌套,我将它修改为以下形式:

.projects-list {
  ...

  & li {
    & > div {...}
  }

  & a {
    ...

    &:hover,
    &:focus {...}

    &::after {...}
  }

  @media (min-width: 640px) {...}
}

复制代码

基本的嵌套需要前置的 & .伪类和选择器在Sass和CSS中是相同的.媒体查询不需要前置 & .

另外值得注意的是 @nest .正如 文档 中提到的,复杂的嵌套可能需要引入 @nest 来代替&.这个项目我还没有用到,或许将来用得到.

拓展和占位类

Sass中的 @extend 和占位类是我经常使用的两个特性。下面是Futura头部的样式示例:

%futura {
  font-family: 'futura-pt', helvetica, sans-serif;
}

%futura-heading {
  @extend %futura;
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
}

复制代码






请到「今天看啥」查看全文