惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
Y
Y Combinator Blog
雷峰网
雷峰网
Last Week in AI
Last Week in AI
Jina AI
Jina AI
月光博客
月光博客
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News | PayPal Newsroom
H
Heimdal Security Blog
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
P
Privacy International News Feed
I
Intezer
V
Vulnerabilities – Threatpost
The GitHub Blog
The GitHub Blog
L
LINUX DO - 最新话题
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
W
WeLiveSecurity
Security Latest
Security Latest
PCI Perspectives
PCI Perspectives
The Hacker News
The Hacker News
T
Threatpost
C
Check Point Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Latest news
Latest news
L
LINUX DO - 热门话题
J
Java Code Geeks
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog

一颗小树

周更的第 100 篇 改变阅读方式 宝贵的人生建议 小树的工具库 2023 读《重构》有感 仅需 10 分钟,用 GPTs 实现文章总结助手 高质量的需求交付 产品始于问题,而不是解决方案 如何更好地休息 最优解人生 与体重斗,其乐无穷 结构化 prompt = 数字员工? 持续创作的法门 如何降低知识焦虑 7 月思维碎片 N 倍生产力提升:我的 AI 助理 Indie Hacker,互联网打工人的下一个出路? 如何成就伟大事业 夏日碎片 小报编辑的自我修养 一颗小树 #49 投入真实生活 一颗小树 #48 过年杂记 一颗小树 #47 我的人生信念(2023) 一颗小树 #46 回本就卖 一颗小树 #45 规划和落地 小树的 2022 年终总结 一颗小树 #44 构建高质量信源 一颗小树 #43 我的 2022 书单 一颗小树 #42 阳了怎么办 一颗小树 #41 一人企业 一颗小树 #40 非必要别正常啦 一颗小树 #39 阅读和创造 一颗小树 #38 疫情生活碎片 一颗小树 #37 基于多维表格的可转债投资系统 一颗小树 #36 飞盘初体验 一颗小树 #35 雁栖湖半日游 一颗小树 #34 初探多维表格 一颗小树 #33 回不去的名字叫家乡 一颗小树 #32 生活需要留白 一颗小树 #31 Figma 的成功之道 一颗小树 #30 拓宽自己 拥抱善意 一颗小树 #29 有关下雨的记忆 一颗小树 #28 隐入尘烟 一颗小树 #27 找到并坚持自己的热爱 一颗小树 #26 好产品的“差”改版 一颗小树 #25 吹吹南澳岛的海风 一颗小树 #24 代码重构的一点心得 一颗小树 #23 和团队新同学的对话 一颗小树 #22 从《干法》中学到的 一颗小树 #21 阿里四年我的收获和感想 一颗小树 #20 周更半年我学到的事 一颗小树 #19 慢慢来比较快 一颗小树 #18 只规划每天最重要的三件事 一颗小树 #17 裁员潮下的反思 一颗小树 #16 纪录片的力量在于真实 一颗小树 #15 世界很小但很好 一颗小树 #14 让自己成为问题的终结者 一颗小树 #13 别忘记你的热爱 一颗小树 #12 聊聊写作这件事 一颗小树 #11 开始投资前更重要的事 一颗小树 #10 疫情囤货指南 一颗小树 #9 疫情之下 重建内心的秩序 一颗小树 #8 不要倒在黎明前 一颗小树 #7 从小孩子身上学到的事 一颗小树 #6 和自己的产品一起成长 一颗小树 #5 技术对生产力的的变革是不可阻挡的 一颗小树 #4 暴风雨的意义 一颗小树 #3 投资成功,是我们变成一个更好的人之后自然的结果 一颗小树 #2 持续学习来应对这个复杂多变的世界 一颗小树 #1 任天堂和上岭村 一颗小树 #0 这是写给你们的第一封信 游戏改变世界 把自己给开源了 构建自己的不为清单 有爱和被爱 做了一点微小的工作 小树的 2021 年终总结 小树的 2020 年终总结 与其感慨路难行,不如马上出发 阿里前端也切图?不,人工智能帮你做 如何写好简历,拿到大厂 offer 的敲门砖 任时光匆匆流去 | 2019 年终总结 聊聊在阿里远程办公那点事儿 在 D2 做主持人是怎样一种体验? 提高工作效率的几个方法 有限状态机在 CSS 动画中的应用 「译」React 项目结构和组件命名之道 编写小而美函数的艺术 使用纯粹的JS构建 Web Component 翻译计划-状态管理请三思 利用Dawn工程化工具实践MobX数据流管理方案 高性能 MobX 模式(part 3)- 用例教程 高性能 MobX 模式(part 2)- 响应变化 技术文章写法浅谈 翻译计划-用node.js开发一个可交互的命令行应用 无他,唯手熟尔-前端实习面试题篇 工欲善其事必先利其器-前端实习简历篇 手把手带你用原生js实现css属性的set和get 我们来翻翻元素样式的族谱-getComputedStyle 把简单做好也不简单-css水平垂直居中
翻译计划-从sass到PostCSS
也树 · 2017-01-25 · via 一颗小树

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

原文链接:https://tylergaw.com/articles/sass-to-postcss 译者:Icarus 邮箱:xdlrt0111@163.com

第一步是列出我 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;
}

这是一个用例:

.my-heading {
  @extend %futura-heading;
}

我在之前了解过 CSS 自定义属性的用法。这里有一个正在进行中的@apply规则的规范与之相关。@apply允许储存一系列的属性并且在选择器引用。我用@apply来代替 Sass 的extend.

回到setup.css来,我更新了 Futura 头部的属性:

:root {
  ...

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

  --franklin-heading: {
    @apply --franklin;
    font-weight: 700;
    line-height: 1.1;
    text-transform: uppercase;
  };
}

这里是一个示例:

.my-heading {
  @apply --franklin-heading;
}

@apply不是继承.在目前的 cssnext 中,@apply将属性和值直接复制到每条规则中.这是个小项目所以没问题.但是在大型的项目中,可能会导致样式冗余,项目非常臃肿.这种情况下最好还是使用通用类名来适用相似情况.

现在我的网站看起来和之前一样了.项目页是个例外.它的每个磁贴区域都有不同颜色.接下来我会解释怎么在没有 Sass 的情况下正确且高效的编写样式.

A screenshot of tylergaw.com/projects

带参数的混合宏

我用 Sass 的混合宏来让项目编写样式更简便.这个混合宏有一个磁贴颜色的参数.以下是这个project-block的混合宏.

@mixin project-block ($c) {
  background-color: $c;

  a {
    color: $c;

    &:hover {
      background-color: $c;
      color: $offwhite);
    }
  }
}

下面是一个示例:

.p-jribbble {
  @include project-block(#ff0066);
}

在写这篇文章的时候,我还没有在 CSS 找到能模拟这个功能的特性.自定义属性配合@apply不是函数,所以我们不能为它传递参数.在将来,自定义选择器可能会允许使用参数.在草案规范中有一个看起来很有前途的复杂示例.但我承认现在我还没完全明白它是怎么工作的.

这不意味着我运气不好.我写 CSS 的时间要长于 Sass,但也没多久.我还用了另一个正进行中的规范特性,matches选择器.

下面是一个代替project-block混合宏的 CSS 示例:

.p-jribbble,
.p-jribbble a:matches(:hover, :focus) {
  background-color: var(--color-jrb);

  & a {
    color: var(--color-jrb);
  }
}

颜色变量是早些在文件中:root作用域定义的.cssnext 将以上 CSS 编译为:

.p-jribbble,
.p-jribbble a:hover,
.p-jribbble a:focus {
  background-color: #ff0066
}

.p-jribbble a,
.p-jribbble a:hover a,
.p-jribbble a:focus a {
  color: #ff0066;
}

最后两个选择器...a a:hover...a a:focus匹配不到任何元素.他们是不必要的.但是除了占用几比特的空间他们也没有任何影响.为了代码的可读性,我更倾向于a选择器的嵌套.

更多 PostCSS 特性

为了样式按顺序回归,我决定利用更多的 PostCSS 插件.我用css mqpacker来合并使用相同查询条件的媒体查询.我也用cssnano来优化代码.

这也是为什么我期待去使用 PostCSS.使用 Sass 的时候我感觉困在当前的特性中.但因为 PostCSS 本质是一个插件集合在工作,更具拓展性.如果我有特殊需要,我可以自己来写一个插件.它的潜力令人兴奋.

我妥协了

在使用这个新工具工作了几天后,我完全投入进去了.从 Sass 转向新的 CSS 语法非常简单,并且是在五六年间我每个项目都用 Sass 编写的情况下.

我喜欢这个思想转变.cssnext 对 CSS 的处理很像 Babel 对 Javascript.它们都允许你去使用未来的特性来编写代码.