PostCSS实战使用

Posted Web手艺人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostCSS实战使用相关的知识,希望对你有一定的参考价值。


PostCSS简介

PostCSS实战使用

PostCSS 本身是一个功能比较单一的工具。它提供了一种方式用 javascript 代码来处理 CSS。它负责把 原始CSS 代码解析成抽象语法树结构(Abstract Syntax Tree,AST),再交由插件来进行处理,最后产出处理过后的 CSS。工作流程大概如下:

PostCSS实战使用

与Sass、Less等关联与对比

  • 并不是像 Sass、Less 这种预处理(pre-processor)语言,也不是按字面理解的后处理(post-processor)语言

  • 使用 Sass 与 Less 语法基本固定,而使用 PostCSS 的语法取决于所选择的插件

  • Sass 与 Less 中的语法,可以在 PostCSS 通过插件实现

  • PostCSS 牛逼之处是它的插件体系,通过海量插件的灵活搭配,PostCSS 能实现的功能也远远比 Sass、Less 强大,可以完全根据各种不同的业务场景,做到可定制化

PostCSS使用

这里以 webpack 为例,介绍PostCSS的使用。在 webpack.config.js 配置中使用 PostCSS 主要通过 postcss-loader (需要在 style-loadercss-loader 之前);同时一般会搭配 postcss.config.js,配置所使用的插件以及插件选项

webpack.config.js

 
   
   
 
  1. const path = require('path');

  2. const devMode = process.env.NODE_ENV !== 'production';

  3. const CleanWebpackPlugin = require('clean-webpack-plugin');

  4. const htmlWebpackPlugin = require('html-webpack-plugin');

  5. const MiniCssExtractPlugin = require("mini-css-extract-plugin");

  6. module.exports = {

  7.    entry: './src/index.js',

  8.    output: {

  9.        filename: devMode ? 'bundle.js' : 'bundle.[hash:6].js',

  10.        path: path.resolve(__dirname, './dist'),

  11.    },

  12.    module: {

  13.        rules: [

  14.            {

  15.                test: /.css$/,

  16.                exclude: /node_modules/,

  17.                use: [

  18.                    MiniCssExtractPlugin.loader,

  19.                    {

  20.                        loader: 'css-loader',

  21.                        options: {

  22.                            minimize: devMode ? false : true,

  23.                            importLoaders: 1

  24.                        }

  25.                    },

  26.                    {

  27.                        loader: 'postcss-loader'

  28.                    }

  29.                ]

  30.            }, {

  31.                test: /.js$/,

  32.                exclude: /node_modules/,

  33.                use: [{

  34.                    loader: 'babel-loader',

  35.                    options: {

  36.                        presets: ['env']

  37.                    }

  38.                }]

  39.            }

  40.        ]

  41.    },

  42.    plugins: [

  43.        new CleanWebpackPlugin(['dist']),

  44.        new HtmlWebpackPlugin({

  45.            template: './src/index.html'

  46.        }),

  47.        new MiniCssExtractPlugin({

  48.            filename: devMode ? '[name].css' : '[name].[hash:6].css'

  49.        })

  50.    ],

  51.    devtool: 'source-map'

  52. };

postcss.config.js

 
   
   
 
  1. module.exports = {

  2.    plugins: [

  3.        require('autoprefixer'),

  4.        require('postcss-advanced-variables'),

  5.        require('postcss-mixins'),

  6.        require('postcss-nested'),

  7.        require('postcss-preset-env')({

  8.            stage: 0

  9.        })

  10.    ]

  11. }

一些常用插件介绍

postcss-import

针对 postcss 中的 @import 进行处理。通常为插件列表第一个插件,让通过 @import 引入进来的 css 文件,也能被后续插件处理

  • 编译前:

 
   
   
 
  1. /* index.css */

  2. @import 'global_import_test.css';

  3. /* global_import_test.css */

  4. body {

  5.    background-color:#f5f0b478;

  6. }

  • 编译后:

 
   
   
 
  1. body {

  2.    background-color:rgba(245, 240, 180, 0.47059);

  3. }

stylelint

css语法检查,与 js 中的 ESlint等类似。配置 .stylelintrc 指定检查规则,配置 .stylelintignore 指定忽略目录

  • .stylelintrc 样例

 
   
   
 
  1. {

  2.    "extends": "stylelint-config-standard",

  3.    "rules": {

  4.        "string-quotes": "single",

  5.        "indentation": 4,

  6.        "color-hex-length": "long",

  7.        "at-rule-no-unknown": [true, {

  8.            ignoreAtRules: ["/^mixin/", "include"]

  9.        }]

  10.    }

  11. }

  • .stylelintignore 样例

 
   
   
 
  1. node_modules

  2. dist

  • 校验效果图 

autoprefixer

自动添加属性前缀,数据来源为 Can I USe。需要结合 browserslist 来使用

  • 编译前:

 
   
   
 
  1. .autoprefixer {

  2.    display: flex;

  3.    flex-direction: column;

  4. }

  • 编译后:

 
   
   
 
  1. .autoprefixer {

  2.    display: -webkit-box;

  3.    display: -ms-flexbox;

  4.    display: flex;

  5.    -webkit-box-orient: vertical;

  6.    -webkit-box-direction: normal;

  7.        -ms-flex-direction: column;

  8.            flex-direction: column;

  9. }

postcss-preset-env

允许使用未来的 css 规则或属性,把css规则转化成旧版本浏览器支持的规则。支持配置 stage

  • 编译前:

 
   
   
 
  1. .new-property {

  2.    @custom-media --viewport-medium (400px <= width <= 700px);

  3.    @custom-selector :--heading h1, h2, h3;

  4.    :--heading {

  5.        font-family: system-ui;

  6.        color: #e42d1578;

  7.        @media (--viewport-medium) {

  8.            color: #6bca1d78;

  9.            margin-block: 0;

  10.        }

  11.    }

  12. }

  • 编译后:

 
   
   
 
  1. .new-property h1,

  2.    .new-property h2,

  3.    .new-property h3 {

  4.        font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue;

  5.        color: rgba(228, 45, 21, 0.47059);

  6.    }

  7. @media (min-width: 400px) and (max-width: 700px) {

  8.    .new-property h1,

  9. .new-property h2,

  10. .new-property h3 {

  11.        color: rgba(107, 202, 29, 0.47059);

  12.        margin-top: 0;

  13.        margin-bottom: 0;

  14.    }

  15. }

postcss-advanced-variables

允许类似 Sass 一样,使用变量。

  • 编译前:

 
   
   
 
  1. $content-color: #f3cece;

  2. .postcss-advanced-variables {

  3.    background-color: $content-color;

  4. }

  • 编译后:

 
   
   
 
  1. .postcss-advanced-variables {

  2.    background-color: #f3cece;

  3. }

postcss-mixins

允许使用类似 Sassmixins

  • 编译前:

 
   
   
 
  1. @mixin mixin-bold-font {

  2.    font-weight: bold;

  3. }

  4. body {

  5.    @include mixin-bold-font;

  6. }

  • 编译后:

 
   
   
 
  1. body {

  2.    font-weight: bold;

  3. }

postcss-nested

允许类似 Sass 一样,使用规则嵌套,同时支持 BEM 规则

  • 编译前:

 
   
   
 
  1. .bem-test {

  2.    &__content {

  3.        font-size: 20px;

  4.    }

  5.    $--big {

  6.        font-size: 26px;

  7.    }

  8. }

  • 编译后:

 
   
   
 
  1. .bem-test__content {

  2.    font-size: 20px;

  3. }

  4. .bem-test--big {

  5.    font-size: 26px;

  6. }

附:BEM 规则

  • Block——块

    块即是通常所说的 Web 应用开发中的组件或模块。每个块在逻辑上和功能上都是相互独立的

  • Element——元素

    元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其他元素。

  • Modifier——修饰符

    修饰符用来定义块或元素的外观和行为。同样的块在应用不同的修饰符之后,会有不同的外观。

编写插件

如果市面上已有的插件,都不能满足你的需求,你仍可以选择根据 PostCSS 提供的 API ,自己编写一个插件。在编写插件之前,再次回顾 PostCss 的工作流程,主要分以下几步:

  • PostCSS 把 CSS 源文件解析为 js AST 对象

  • PostCSS 插件遍历 AST 对象,对 选择器 和 属性 ,进行 增加/删除/修改 操作

  • PostCSS 根据 AST ,重新编译出 CSS 文件

下面展示一个简单插件的例子:

 
   
   
 
  1. var postcss = require('postcss');

  2. module.exports = postcss.plugin('postcss-test-plugin', function() {

  3.  return function(root) {

  4.    root.walkRules(function(rule) {

  5.      rule.walkDecls(/^overflow-?/, function(decl) {

  6.        if (decl.value === 'scroll') {

  7.          var hasTouch = rule.some(function(i) {

  8.            return i.prop === '-webkit-overflow-scrolling';

  9.          });

  10.          if (!hasTouch) {

  11.            rule.append({

  12.              prop: '-webkit-overflow-scrolling',

  13.              value: 'touch'

  14.            });

  15.          }

  16.        }

  17.      });

  18.    });

  19.  };

  20. });

其中 root.walkRules 遍历 CSS 中选择器, rule.walkDecls 遍历选择器中的 CSS 规则。最终实现效果为,对含有 overflow-?:scroll 的选择器中,若没有配置 -webkit-overflow-scrolling,则添加 -webkit-overflow-scrolling:touch 规则。

总结

对于 CSS 的处理一直都是 Web 开发中的一个复杂问题,其中一部分来源于 CSS 规范,一部分来源于不同浏览器实现带来的兼容性问题。PostCSS 为处理 CSS 提供了一种新的思路。通过 PostCSS 强大的插件体系,可以对 CSS 进行各种不同的转换和处理。

以上是关于PostCSS实战使用的主要内容,如果未能解决你的问题,请参考以下文章

solr分布式索引实战分片配置读取:工具类configUtil.java,读取配置代码片段,配置实例

postcss 不能与 webpack 5 和 sass 结合使用

Webpack + postcss + 主题 + 热加载

深入浅出的webpack构建工具---PostCss

Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段

PostCSS 的嵌套语法用于 :hover 和 :focus