css workflow

历史

上古时期:刀耕火种

  • 最原始的预处理: 模板插入
.container {
    left: <%= left%>px;
}
  • 手写前缀
.info {
  -webkit-transition: width .3s;
  -moz-transition: width .3s;
  -ms-transition: width .3s;
  -o-transition: width .3s;
  transition: width .3s;//标准写法放最后
}

工业革命

  • 通过编辑器插件手动处理前缀

随着前后端分离,以及web前端工程化的日益完善,逐渐出现一些css工程化的解决方案

第二次工业革命

  • 各种预处理器
  • 后处理器
  • postcss

css 预处理器

  • sass/scss
  • less
  • stylus

特性:

  • variables
less
@base: #f938ab;
border: 1px solid @base;

sass
$base: #F90;
border: 1px solid $base;
  • Nesting
#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}
//输出

  • Mixins
less
.transition(value) {
  -webkit-transition: value;
     -moz-transition: value;
       -o-transition: value;
          transition: value;
}
.foo {
  .transition(width .3s);
}

sass
@mixin transition($value) {
  -webkit-transition: $value;
     -moz-transition: $value;
       -o-transition: $value;
          transition: $value;
}
.foo {
  @include transition(width .3s);
}
  • Operations
  • Functions
  • namespaces
  • scope
  • import
  • ...

实现原理:

  • 取到 DSL源代码的分析树
  • 将含有动态生成相关节点的分析树转换为静态分析树
  • 将静态分析树转换为CSS的静态分析树
  • 将CSS的静态分析树转换为CSS 代码

####特点: 逻辑处理能力强,可以优化项目结构,但是采用特殊语法,和预处理框架耦合度高

css 后处理器

  • 压缩 clean-css
  • 自动加前缀 AntoPrefixer
  • 可攻可受的css Grace

看一下上面预处理器是如何前缀的?分别写mixinx 然后再入引用。 后处理器如何处理的?

.foo {
  transition: width .3s;
}
//根据你的Browserslist配置
转换成
.foo {
  -webkit-transition:  width .3s;
     -moz-transition:  width .3s;
       -o-transition:  width .3s;
          transition:  width .3s;
}

实现原理:

  • 将源代码做为CSS解析,获得分析树
  • 对CSS的分析树进行后处理
  • 将CSS的分析树转换为CSS代码

特点:

使用原生语法,更贴近未来标准,但是逻辑处理等方便偏弱

postcss 前后通吃

前后通吃,既能实现预处理功能,又能处理后处理器做的事,而且功能不仅如此,采用插件系统,即插即用。

postcss让css 工作流变得更加清晰。

未来css工作流可能是 原生css未来标准 + postcss等 处理器。 现在项目中流行的方式是 预处理+postcss结合使用。

postcss

PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

postcss是啥

PostCSS是CSS变成JavaScript的数据,使它变成可操作。PostCSS是基于JavaScript插件,然后执行代码操作。PostCSS自身并不会改变CSS,它只是一种插件,为执行任何的转变铺平道路。

postcss可以做啥

PostCSS 接收一个 CSS 文件并提供了一个 API 来分析、修改它的规则(通过把 CSS 规则转换成一个抽象语法树的方式)。在这之后,这个 API 便可被许多插件利用来做有用的事情,比如寻错或自动添加 CSS vendor 前缀。 PostCSS插件可以像预处理器,它们可以优化和autoprefix代码;可以添加未来语法;可以添加变量和逻辑;可以提供完整的网格系统;可以提供编码的快捷方式等等。

postCSS可以做很多,但是他自身又不会去做什么,你可以通过配置插件或者结合其他来完成你想要的效果。

尽管表面上它看起来是一个预处理器,其实它不是一个预处理器
尽管表面上它看起来是一个后处理器,其实它也不是一个后处理器
尽管它可以促进、支持未来的语法,其实它不是未来语法
尽管它可以提供清理、优化代码这样的功能,其实它不是清理、优化代码的工具
它不是任何一件事情,这也意味者它潜力无限,你可以根据自己的需要配置你需要的功能

你可以在这里list或者这里searchable catalog来查找 postcss的plugins。

readme

解决全局 CSS 的问题

  • postcss-use 允许你在 CSS 里明确地设置 PostCSS 插件,并且只在当前文件执行它们。
  • postcss-modulesreact-css-modules 可以自动以组件为单位隔绝 CSS 选择器。
  • postcss-autoreset 是全局样式重置的又一个选择,它更适用于分离的组件。
  • postcss-initial 添加了 all: initial 的支持,重置了所有继承的样式。
  • cq-prolyfill 添加了容器查询的支持,允许添加响应于父元素宽度的样式.

提前使用先进的 CSS 特性

  • autoprefixer 添加了 vendor 浏览器前缀,它使用 Can I Use 上面的数据。
  • [css-next] Use tomorrow’s CSS syntax, today。
  • postcss-preset-env Use tomorrow’s CSS syntax, today。

更佳的 CSS 可读性

  • [precss] 囊括了许多插件来支持类似 Sass 的特性,比如 CSS 变量,套嵌,mixins 等。
  • postcss-sorting 给规则的内容以及@规则排序。
  • postcss-utilities 囊括了最常用的简写方式和书写帮助。
  • [short] 添加并拓展了大量的缩写属性。

图片和字体

提示器(Linters)

  • stylelint 是一个模块化的样式提示器。
  • stylefmt 是一个能根据 stylelint 规则自动优化 CSS 格式的工具。
  • doiuse 提示 CSS 的浏览器支持性,使用的数据来自于 Can I Use。
  • colorguard 帮助你保持一个始终如一的调色板。

其它

  • postcss-rtl 在单个 CSS 文件里组合了两个方向(左到右,右到左)的样式。
  • cssnano 是一个模块化的 CSS 压缩器。
  • lost 是一个功能强大的 calc() 栅格系统。
  • rtlcss 镜像翻转 CSS 样式,适用于 right-to-left 的应用场景。

语法

PostCSS 可以转化样式到任意语法,不仅仅是 CSS。 如果还没有支持你最喜欢的语法,你可以编写一个解释器以及(或者)一个 stringifier 来拓展 PostCSS。

  • sugarss 是一个以缩进为基础的语法,类似于 Sass 和 Stylus。
  • postcss-syntax 通过文件扩展名自动切换语法。
  • postcss-html 解析类 HTML 文件里<style>标签中的样式。
  • postcss-markdown 解析 Markdown 文件里代码块中的样式。
  • postcss-jsx 解析源文件里模板或对象字面量中的CSS。
  • postcss-styled 解析源文件里模板字面量中的CSS。
  • postcss-scss 允许你使用 SCSS (但并没有将 SCSS 编译到 CSS)
  • postcss-sass 允许你使用 Sass (但并没有将 Sass 编译到 CSS)
  • postcss-less 允许你使用 Less (但并没有将 LESS 编译到 CSS)
  • postcss-less-engine 允许你使用 Less (并且使用真正的 Less.js 把 LESS 编译到 CSS)
  • postcss-js 允许你在 JS 里编写样式,或者转换成 React 的内联样式/Radium/JSS。
  • postcss-safe-parser 查找并修复 CSS 语法错误。
  • midas 将 CSS 字符串转化成高亮的 HTML。

文章

你可以在 awesome-postcss 列表里找到更多优秀的文章和视频。

使用

每个项目遇到的场景都是不一样,这里会介绍集中常用的插件的使用,通过这几些来了解下postcss的强大之处

  1. 在你的构建工具中找到postcss对应的扩展并添加。
  2. 查找你所需要的postcss插件 添加到postcss处理队列中。

你可以使用webpack gulp fis 或者直接CLI来使用,鉴于前端现在大多用的webpack,我们后面介绍的集中都是基于webpack的,我们的webpack已经有太多东西来处理了,所以postcss我们会单独放到一个文件来做配置 .postcssrc.js 或者 postcss.config.js(当然你可以命名其他名字,然后修改path,一般我们不会修改)

postcss-loader

首先是 postcss-loader 你需要把post-cssloader加入到你的webpack中去,一般我们不会单独使用,而是结合css-loader style-loader等,注意:你需要把它放到style-loader css-loader后面,但是要放到一些预处理loader less-loader sass-loader前面(loader加载顺序从右往左)

npm install postcss-loader

//webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          'postcss-loader'
        ]
      }
    ]
  }
}

// postcss.config.js
// 一般配置文件我们只需要关注plugins就好啦,当然还有其他配置项
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
    plugins: {
        "postcss-import": {}, 
        "postcss-url": {}, 
        "autoprefixer": {}
    }
}

postcss-import

主要是解决@import引入路径问题。使用这个插件,可以让你很轻易的使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松。

//xx.css
@import "normalize.css"; /* == @import "../node_modules/normalize.css/normalize.css"; */

postcss-url

该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。

autoprefixer

自动添加浏览器厂商的私有前缀,它使用 Can I Use 上面的数据。当然你可以根据项目需要,做相应浏览器的兼容,你可以创建 .browserslistrc 或者我们更常用的办法是在package.json的 browserslist字段添加。其他工具比如 babel-preset-env stylelint等都可以共享此浏览器配置。

    {
        "browserslist": [
            "> 1%",
            "last 2 versions",
            "not ie <= 8",
            "iOS >= 7",
            "Firefox >= 20",
            "Android > 3.2"
        ]
    }

还需要注意的一点是由于autoprefixer是css常见的需求,所以很多插件其实已经内置了此功能,比如 postcss-cssnext postcss-nano postcss-preset-dev

cssnano

主要用来压缩和清理CSS代码。 在webpack中 css-loader已经具有cssnano功能。你可以在postcss-loader里面显示的使用并配置。 cssnano是一个非常强大的CSS优化的插件包,他汇聚了20几个插件,即插即用。你可能根据自己的需求进行配置,甚至是完全禁用。具体参数 见这里

  plugins: {
    cssnano: {
      preset: "advanced", //cssnano-preset-advanced
      autoprefixer: false, //比如你已经单独使用了autoprefixer 或者使用了postcss-cssnext等具备autoprefixer功能的plugin
      "postcss-zindex": false  //这里面有坑,他会重新计算页面的z-index,假如你在其他组件里面有设置z-index,会失效。
    }
  }

未来语法之:postcss-cssnext

ccssnext。该插件可以让我们使用CSS未来的特性,其会对这些特性做相关的兼容性处理。BUT变化太TM快了,目前被不再维护 被postcss-preset-env 取代 相关特性 变量 混入 逻辑等

  plugins: {
    'postcss-cssnext': {},
  }

未来语法之:postcss-preset-env

post-cssnext下一代 更加强大。资料 BUT假如你有用happypack去做webpack的性能优化的话,请使用post-cssnext。happypack有点“老了”根本配不上postcss-preset-env 2333~

  plugins: {
    'postcss-preset-env': {},
  }

REM布局方案

移动端现在流行的rem布局,我们可以通过 postcss插件来做自动配置。

具体实现不多说,flexable

方案1: 配合sublime插件 cssrem

sublime配置插件

{
    "px_to_rem": 75,
    "max_rem_fraction_length": 6,
    "available_file_types": [".css", ".less", ".sass",".vue"]
}

方案2: 利用sass等预处理工具,编写pxTorem function等

//css
$brower_default_font_size: 16px !default;
html{
    font-size: $brower_default_font_size;
}
@function pxTorem($px){
    @return $px / $brower_default_font_size * 1rem;
}

container {
    width: pxTorem(200px);
}

方案3: 也就是我们的主角,postcss插件,我常用的是postcss-pxtorem(last publish:2 years ago)

当然还有其他相似插件postcss-px2rem(last publish:3 years ago),两者都没有提供exclude

核心配置:

postcss.config.js
module.exports = {
    plugins: {
        "postcss-pxtorem": {
            rootValue: 75,
            unitPrecision: 5,
            propList: ['*'],
            selectorBlackList: [],
            replace: true,
            mediaQuery: false,
            minPixelValue: 12,
        }
    }
}

从此移动端我们就可以愉快的使用设计稿PX来搞啦~其他交给postcss来搞定。

vw布局方案

vw布局方案采用的是 postcss-px-to-viewport

module.exports = {
  plugins: {
    "postcss-px-to-viewport": {
      viewportWidth: 750, //视窗的宽度,对应的是我们设计稿的宽度,一般是750
      viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
      unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
      viewportUnit: "vw", // 指定需要转换成的视窗单位,建议使用vw
      selectorBlackList: [".ignore", ".hairlines"], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
      minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
      mediaQuery: false, // 是否允许在媒体查询中转换`px`
      exclude:/node_modules/i, //排除第三方库
    },
  }
};

从此移动端我们就可以愉快的使用设计稿PX来搞啦~

其他

  • preCSS预处理器 和sass类似 拥有变量,嵌套,循环,混入等功能
  • postcss-sprites 生成雪碧图
  • postcss-svgo 给内联SVG做优化
  • postcss-modules css modules...
  • CSS Grace 修复IE各种bug,兼容旧浏览器的各种 Hack,让你无需担忧兼容性 包括IE6!
  • postcss-simple-vars 实现sass类变量
  • postcss-mixins [you must set this plugin before postcss-simple-vars and postcss-nested]
  • postcss-nested 嵌套

聊一聊 postcss-preset-env

css未来语法原来由于种种原因导致不敢用的,比如image-set现在你可以撸起袖子干了 css-next升级版link

image-set兼容性

avatar

转换后 dpr2下

转换后 dpr3下

  • stage0

    嵌套

article {
  & p {
    color: #333;
  }
}

  • stage1

    自定义media queries

custom media queries
@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {}

  • stage2

    可以根据用户设备的分辨率匹配合适的图像

可以根据用户设备的分辨率匹配合适的图像
p {
  background-image: image-set(
    "foo.png" 1x,
    "foo-2x.png" 2x,
    "foo-print.png" 600dpi
  );
}

  • stage3

    自定义属性

custom properties
img {
  --some-length: 32px;
  height: var(--some-length);
}
---> 转换为
img {
  height: 32px;
  height: var(--some-length);
}

摸我~

--

postcss强大的功能不止如此,总之当我们配置好postcss工作流之后,我们之后需要关注css就好了,剩下兼容,优化等问题,我们丢给postcss就好啦

开发 PostCSS插件

相关

Last Updated: 3/2/2020, 10:17:37 AM