PostCSS真的太好用了!

PostCSS官网有着这样的对PostCSS特性介绍,箭头后面是对应功能的插件及其github地址。

PostCSS是一款使用插件去转换CSS的工具,有许多非常好用的插件,例如autoprefixer,cssnext以及CSS Modules。而上面列举出的这些特性,都是由对应的postcss插件去实现的。而使用PostCSS则需要与webpack或者parcel结合起来。
在Parcel中使用PostCSS的方法:添加配置文件.postcssrc(JSON),.postcssrc.js或者是postcss.config.js。
拿 .postcssrc 文件来举例:

{
  "modules": true,
  "plugins": {
    "autoprefixer": {
      "grid": true
    }
  }
}

Plugins 在 plugins 对象中被指定为 key,并使用对象的值定义选项。如果插件没有选项,只需将其设置为 true 即可。
下面我将对根据官方readme的演示demo,对各个插件进行一一介绍,并添加一些隐藏在插件背后的知识点的说明。

1.什么是Autoprefixer?

首先明确一点Autoprefixer是一个根据can i use解析css并且为其添加浏览器厂商前缀的PostCSS插件。
不加任何vender prefix的通常写法。

::placeholder {
    color: gray;
}

Autoprefixer将使用基于当前浏览器支持的特性和属性数据去为你添加前缀。你可以尝试下Autoprefixer的demo:http://autoprefixer.github.io/

image

由上图可以看出,像没有浏览器差异已经完全符合W3C标准的css2.1属性display,position等,Autoprefixer不会为其加前缀,而像css3属性transform就会为其加前缀,其中--webkit是chrome和safari前缀,--ms则是ie的前缀,像firefox由于已经实现了对transform的W3C标准化,因此使用transform即可。

因此Autoprefixer是一个非常有用的加速前端开发的一个工具,但是它需要基于PostCSS去发挥作用。

如果对vender prefix存疑,可以去看我的这篇博客:rem / Vender Prefix / CSS extensions

2.什么是postcss-cssnext?

postcss-cssnext语法input:

:root {
  --fontSize: 1rem;
  --mainColor: #12345678;
  --centered: {
      display: flex;
      align-items: center;
      justify-content: center;
  };
}
body {
    color: var(--mainColor);
    font-size: var(--fontSize);
    line-height: calc(var(--fontSize) * 1.5);
    padding: calc((var(--fontSize) / 2) + 1px);
}
.centered {
    @apply --centered;
}

浏览器可用语法output:

body {
    color: rgba(18, 52, 86, 0.47059);
    font-size: 16px;
    font-size: 1rem;
    line-height: 24px;
    line-height: 1.5rem;
    padding: calc(0.5rem + 1px);
}
.centered {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
        -ms-flex-align: center;
            align-items: center;
    -webkit-box-pack: center;
        -ms-flex-pack: center;
            justify-content: center;
}

粗略看了一遍演示demo,http://cssnext.io/playground/,感觉既好用又不好用。
好用的地方在于通过var()和calc()进行css属性值的计算,也有@apply这样的应用大段规则的写法,也可以借此去了解一些新的css草案特性;不好用的地方在于有一定的学习成本,而且在前期与webpack,gulp以及parcel进行结合时也需要花费一定时间,并且如果有新的前端组成员加入,必须要掌握这种cssnext的语法。
这样做有些似乎在尝试将css变为一种可以进行逻辑处理的语言,但是我个人认为这对于css这样的灵活的需要具象思维并且需要大量调试的语言来说,工作中使用cssnext不是一个很好的选择,但是工作之余可以作为一个学习新的css草案特性的一个入口,待到纳入标准再去使用。

刚开始对自己的想法不确定,因此去看了下前辈们的想法,其中顾铁灵对cssnext的想法与我的想法如出一辙:

CSS 的转译器(transpiler),根据目前仍处于草案阶段、未被浏览器实现的标准把代码转译成符合目前浏览器实现的 CSS。类似 ES6 的 Babel。
相比之下,Autoprefixer 更加具有实用价值,而 cssnext 实现的功能以后浏览器会怎么实现还存疑,感觉只能玩玩。

3.什么是postcss-modules?

在看postcss-modules之前,首先要明确的是CSS Modules的这个概念,关于CSS Modules,可以阅读我翻译的一篇文章:【译】什么是CSS Modules ?我们为什么需要他们?

postcss-modules则是CSS Modules在PostCSS上的实现插件,这里有一篇插件作者本人写的介绍postcss-modules的文章:PostCSS-modules:make CSS great again!

在我有限的开发经验中,只在react中使用过css modules,在vue和angularjs中都没用到过,而且在react中使用时,不会去用postcss-modules这个插件,而是使用react-css-modules这个CSS Modules思想在react中的插件。

下面将给出最简单的入门例子:
在React上下文中,CSS Modules可能像下面这样写:

import React from 'react';
import styles from './table.css';

export default class Table extends React.Component {
    render () {
        return <div className={styles.table}>
            <div className={styles.row}>
                <div className={styles.cell}>A0</div>
                <div className={styles.cell}>B0</div>
            </div>
        </div>;
    }
}

最后渲染出的组件的标签会是如下形式:

<div class="table__table___32osj">
    <div class="table__row___2w27N">
        <div class="table__cell___1oVw5">A0</div>
        <div class="table__cell___1oVw5">B0</div>
    </div>
</div>

如果对为什么会把class名编译成table__table___32osj这样的形式存在疑惑,需要先把css modules搞清楚:【译】什么是CSS Modules ?我们为什么需要他们?

如果需要在开发环境或者生产环境结合webpack去使用,那么可以阅读react-css-modules的官方文档寻找答案。

通过这次探索我们可以发现,前端开发在不同的生态,或者说框架体系下,同一个技术,例如CSS Modules这种将思想,会有对应的实现方式,而我们要掌握的,不仅仅是在某种框架下配置使用的方法,而是这种开发思想。因为学习的核心在于学习知识,而不是无休止的学习工具。

4.什么是stylelint?

这是用来强制开发人员按照团队css规范写css样式的工具,类似eslint。
若想使用,只需要去启用规则即可。

节选一段stylelint作者博文中的话:

没错,你的团队可能在某个地方的某条纯文本wiki中记录了团队的代码样式规范。但是,不容忽视的是人的因素:人总是会犯错——总是在无意之间。
而且即使你很自律地执着遵循某个规范的代码风格,但是你没办法确保你的同事或是你的开源项目的贡献者能够像你一样。没有linter的帮助,你必须人工检查代码样式和错误。而机器存在的意义就是代替人来完成能够自动化实现的任务。linter就是这样的机器,有了linter,你不需要浪费时间检查代码风格,也不需要对每一个代码错误都写一大堆的注释,因此它能够极大程度地减少你花费在代码审阅上的时间。你无须检查代码究竟做了些什么,也无需关心它看起来什么样。

事实与stylelint作者说的是一样的,即使团队有前端开发规范,也会不经意间写出不符合规范的代码,因为每次写css规则前都去规范check一遍不是谁都能做到的,如果团队再没有code review这一关的话,写出各种各样风格的css代码就是一件必然的事了,短期没有什么影响,当项目变得庞大起来,增加新功能或者重写旧功能将会是一件很痛苦的事。

我们主要去关注Rules部分
sytlelint的规则主要有3类,我将从每一类规则中挑一个拿出来作为示例。

  • Possible errors(常见的错误写法,强烈推荐开启)

  • Limit language features(弃用一些正确的写法,中等推荐开启)

  • Stylistic issues(代码风格代码统一,普通建议开启)

  • Possible errors ------ color-no-invalid-hex: 禁止无效的十六进制颜色
    完全形式的十六进制颜色可以是6或者8(7,8位是透明度的值)个字符。同样他们的缩写可以是3或者4个字符。
    options : true
    下面的代码违反规则:

a { color: #00; }
a { color: #fff1az; }
a { color: #12345aa; }

下面的代码符合规则:

a { color: #000; }
a { color: #000f; }
a { color: #fff1a0; }
a { color: #123450aa; }
  • Limit language features ------ color-no-hex:禁止使用十六进制颜色
    options : true
    十六进制的颜色违反规则:
a { color: #000; }
a { color: #fff1aa; }
a { color: #123456aa; }

无效的十六进制色同样违规:

a { color: #foobar; }
a { color: #0000000000000000; }

下面的是符合规则的:

a { color: black; }
a { color: rgb(0, 0, 0); }
a { color: rgba(0, 0, 0, 1); }
  • Stylistic issues ------ color-hex-case: 自动将十六进制色转换为大写或者小写
    Options string: "lower"|"upper"
    可以使用stylelint "foo/*.css" --fix实现同样的功能。
    "小写"
    下面的代码是违规的:
a { color: #FFF; }

下面的是符合规则的:

a { color: #000; }
a { color: #fff; }

"大写"
下面的代码是违规的:

a { color: #fff; }

下面的是符合规则的:

a { color: #000; }
a { color: #FFF; }

更多的stylelint的规则可以查阅:https://github.com/stylelint/stylelint/blob/master/docs/user-guide/rules.md#possible-errors

5.什么是LostGrid?

Lost Grid是一个强大的PostCSS网格系统,可与任何预处理器甚至是原生CSS一起使用。
在这里有非常好的demo展示:http://lostgrid.org/lostgrid-example.html

节选2个展示进行说明。

.ColumnSection__grid div {
    lost-column: 1/1;
}
@media (min-width: 400px) {
    .ColumnSection__grid div {
        lost-column: 1/3;
    }
}
@media (min-width: 900px) {
    .ColumnSection__grid div {
        lost-column: 1/6;
    }
}

大于900px时:


image

小于900px时:


image

.NestingSection__grid {
background: #8eb19d;

}

.NestingSection__grid div {
background: #7ba48d;
lost-column: 1/3;
}

.NestingSection__grid div div {
    background: #68977c;
    lost-column: 1/2;
}
image

经过查看css样式我们发现,其实就是巧用了table布局,before/after伪元素,以及css选择器,以及border-box布局,但其实最最核心的地方还是在于很好的使用了css本身具有的流式布局以及BFC,针对各种情况,在插件内部使用了大量的样式进行约束。


image

在css3的flex布局和grid布局逐渐被浏览器所支持的今天,我个人建议不使用LostGrid插件。

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容