资讯专栏INFORMATION COLUMN

谈谈PostCSS

高胜山 / 3360人阅读

摘要:它们有个统一的名字预处理器。面对以上问题,预处理器给出了非常可行的解决方案变量就像其他编程语言一样,免于多处修改。回到话题中,之所以会出现向预处理器这样子的解决方案,归根结底还是标准发展的滞后性导致的。

前言

现在的前端,javascript的发展有目共睹,框架林立。同时,html也是齐头并进,推出了HTML5标准,并且得到了普及。这样的发展却唯独少了一个角色?

CSS,就是这个看似不起眼的家伙,却在开发中发挥着和js一样重要的作用。css,是一种样式脚本,好像和编程语言有着一定的距离,我们可以将之理解为一种描述方法。这似乎导致css被轻视了。不过,css近几年来正在经历着一次巨变——CSS Module。我记得js的井喷期应该可以说是node带来的,它带来了Module的概念,使得JS可以被工程化开发项目。那么,今天的css,也将越来越美好。如果你喜欢我的文章,欢迎评论,欢迎Star~。欢迎关注我的github博客

正文

既然作为一篇推广PostCSS的文章,我们就应该先来了解一下这是什么,和我们之前讲的CSS Module有啥关系?此处让我为你们娓娓道来。

我想和你们说再见

目前,在工程化开发中,使用最多的应该就是Less、Sass和Stylus。首先,还是介绍一下它们吧。它们有个统一的名字——css预处理器。何为CSS预处理器?应该就是一种可以将你根据它的规则写出来的格式转成css的东西(还是讲的通俗一点)。它们的出现可以说是恰逢其时,解决了css的一些缺憾:

语法不够强大,不能够嵌套书写,不利于模块化开发

没有变量和逻辑上的复用机制,导致在css的属性值中只能使用字面量形式,以及不断重复书写重复的样式,导致难以维护。

面对以上问题,css预处理器给出了非常可行的解决方案:

变量:就像其他编程语言一样,免于多处修改。

Sass:使用「$」对变量进行声明,变量名和变量值使用冒号进行分割

Less:使用「@」对变量进行声明

Stylus:中声明变量没有任何限定,结尾的分号可有可无,但变量名和变量值之间必须要有『等号』。但需要注意的是,如果用“@”符号来声明变量,Stylus会进行编译,但不会赋值给变量。就是说,Stylus 不要使用『@』声明变量。Stylus 调用变量的方法和Less、Sass完全相同。

作用域:有了变量,就必须得有作用域进行管理。就想js一样,它会从局部作用域开始往上查找变量。

Sass:它的方式是三者中最差的,不存在全局变量的概念

Less:它的方式和js比较相似,逐级往上查找变量

Stylus:它的方式和Less比较相似,但是它和Sass一样更倾向于指令式查找

嵌套:对于css来说,有嵌套的写法无疑是完美的,更像是父子层级之间明确关系

三者在这处的处理都是一样的,使用「&」表示父元素

有了这些方案,会使得我们可以在保证DPY、可维护性、灵活性的前提下,编写css样式。

回到话题中,之所以会出现向预处理器这样子的解决方案,归根结底还是css标准发展的滞后性导致的。同时,我们也应该考虑一下,真的只要预处理器就够了吗?往往在项目过大时,由于缺乏模块的概念,全局变量的问题会持续困扰着你。每次定义选择器时,总是要顾及到其他文件中是否也使用了同样的命名。毕竟项目是团队的,而不是个人的。哪是否有方式可以解决这些问题呢?

前人的方法

对于css命名冲突的问题,由来已久,可以说我们前端开发人员,天天在苦思冥想,如何去优雅的解决这些问题。css并未像js一样出现了AMD、CMD和ES6 Module的模块化方案。

那么,回到问题,如何去解决呢?我们的前人也有提出过不同的方案:

Object-Oriented CSS

BEM

SMACSS

方案可以说是层出不穷,不乏有团队内部的解决方案。但是大多数都是一个共同点——为选择器增加前缀。

这可是一个体力活,你可能需要手动的去编写长长的选择器,或许你可以使用预编译的css语言。但是,它们似乎并为解决本质的问题——为何会造成这种缺憾。我们不妨来看看,使用BEM规范写出来的例子:



每次这样子写,估计是个程序员,都得加班吧,哈哈!

一种希望

现在的网页开发,讲究的是组件化的思想,因此,急需要可行的css Module方式来完成网页组件的开发。自从2015年开始,国外就流行了CSS-in-JS(典型的代表,react的styled-components),还有一种就是CSS Module。

本篇谈及后者,需要对前者进行了解的话,自行Google即可

对于css,大家都知道,它是一门描述类语言,并不存在动态性。那么,要如何去形成module呢。我们可以先来看一个react使用postcss的例子:

//example.css

.article {
    font-size: 14px;
}
.title {
    font-size: 20px;
}

之后,将这些命名打乱:

.zxcvb{
    font-size: 14px;
}
.zxcva{
    font-size: 20px;
}

将之命名对应的内容,放入到JSON文件中去:

{
    "article": "zxcvb",
    "title": "zxcva"
}

之后,在js文件中运用:

import style from "style.json";

class Example extends Component{
    render() {
        return (
            
) } }

这样子,就描绘出了一副css module的原型。当然,我们不可能每次都需要手动去写这些东西。我们需要自动化的插件帮助我们完成这一个过程。之后,我们应该先来了解一下postCSS。

我需要认识你

PostCSS是什么?或许,你会认为它是预处理器、或者后处理器等等。其实,它什么都不是。它可以理解为一种插件系统。使用它GitHub主页上的介绍:

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

你可以在使用预处理器的情况下使用它,也可以在原生的css中使用它。它都是支持的,并且它具备着一个庞大的生态系统,例如你可能常用的Autoprefixer,就是PostCSS的一个非常受欢迎的插件,被Google, Shopify, Twitter, Bootstrap和CodePen等公司广泛使用。

当然,我们也可以在CodePen中使用它:

这里推荐大家看一下PostCSS的深入系列

接下来,我们来看一下PostCSS的配置:

这里我们使用webpack+postcss+postcss-loader+cssnext+postcss-import的组合。

首先,我们可以通过yarn来安装这些包:

yarn add --dev webpack extract-text-webpack-plugin css-loader file-loader postcss postcss-loader postcss-cssnext postcss-import

然后,我们配置一下webpack.config.js:

const webpack = require("webpack");
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
  context: path.resolve(__dirname, "src"),
  entry: {
    app: "./app.js";
  },
  module: {
    loaders: [
      {
        test: /.css$/,
        use: ExtractTextPlugin.extract({
          use: [
            {
              loader: "css-loader",
              options: { importLoaders: 1 },
            },
            "postcss-loader",
          ],
        }),
      },
    ],
  },
  output: {
    path: path.resolve(__dirname, "dist/assets"),
  },
  plugins: [
    new ExtractTextPlugin("[name].bundle.css"),
  ],
};

然后在根目录下配置postcss.config.js

module.exports = {
  plugins: {
    "postcss-import": {},
    "postcss-cssnext": {
      browsers: ["last 2 versions", "> 5%"],
    },
  },
};

之后,就可以在开发中使用cssnext的特性了

/* Shared */
@import "shared/colors.css";
@import "shared/typography.css";
/* Components */
@import "components/Article.css";
/* shared/colors.css */
:root {
  --color-black: rgb(0,0,0);
  --color-blue: #32c7ff;
}

/* shared/typography.css */
:root {
  --font-text: "FF DIN", sans-serif;
  --font-weight: 300;
  --line-height: 1.5;
}

/* components/Article.css */
.article {
  font-size: 14px;
  & a {
    color: var(--color-blue);
  }
  & p {
    color: var(--color-black);
    font-family: var(--font-text);
    font-weight: var(--font-weight);
    line-height: var(--line-height);
  }
  @media (width > 600px) {
    max-width: 30em;
  }
}

最后使用webpack进行编译就可以了。

总结

PostCSS,国内还没有太流行起来,不过相信不久的将来也会逐渐的热门,并且国内的资源较少,不过最近新出了一本大漠老师们一起翻译的书——《深入PostCSS Web设计》。有兴趣的人也可以去看一下,学习一些前言的东西。本篇也只是大概的写了一下PostCSS的东西,鉴于国内资源较少,所以参考了一下国外的博文教材,下面会有链接。

如果你对我写的有疑问,可以评论,如我写的有错误,欢迎指正。你喜欢我的博客,请给我关注Star~呦。大家一起总结一起进步。欢迎关注我的github博客

参考链接

PostCSS-modules: make CSS great again!

PostCSS Deep Dive: What You Need to Know

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/115544.html

相关文章

  • 谈谈PostCSS

    摘要:它们有个统一的名字预处理器。面对以上问题,预处理器给出了非常可行的解决方案变量就像其他编程语言一样,免于多处修改。回到话题中,之所以会出现向预处理器这样子的解决方案,归根结底还是标准发展的滞后性导致的。 前言 现在的前端,javascript的发展有目共睹,框架林立。同时,html也是齐头并进,推出了HTML5标准,并且得到了普及。这样的发展却唯独少了一个角色? CSS,就是这个看似不...

    leap_frog 评论0 收藏0
  • 新人领进门 - 收藏集 - 掘金

    摘要:笨办法学前端掘金最近在教任务班的学生造轮子。随着成为主流的组件发布平台,最全的知识汇总前端掘金引言一直是非常热门的话题,因此此系列文章主要从一些基本功能开始讲起,逐步深入了解的新概念。 笨办法学前端 - 掘金最近在教任务班的学生造轮子。我想干脆把源代码开源出来,让自学的同学也看一看吧。于是就有了《笨办法造轮子》系列教程。 没有 webpack、没有 babel、没有 SCSS、没有 r...

    Near_Li 评论0 收藏0
  • 2017-10-18 前端日报

    摘要:前端日报精选无头浏览器初探鼠标无限移动简介译深入分析变更检测发布前必须排查的安全如何开发中文第期关键和减少阻塞渲染的的自动化解决方案译网页设计掘金年最受欢迎的个编程挑战网站简书系列和深入理解掘金发布后台管理系统,没错,它就是你想 2017-10-18 前端日报 精选 无头浏览器 Puppeteer 初探鼠标无限移动 JS API Pointer Lock简介[译] 深入分析 Angul...

    cyrils 评论0 收藏0
  • webpack 大法好 ---- 基础概念与配置(1)

    摘要:不信你命令行里敲个试试敲敲敲当然了想直接运行命令,你需要将添加到系统变量啊。全局安装相同的,运行命令耐心等待安装完成后,你的系统变量里就存在命令了,你可以运行下试试。上诉如果有不懂的,欢迎留言。 再一次见面! Light 还是太太太懒了,距离上一篇没啥营养的文章已经过去好多天。今天为大家介绍介绍 webpack 最基本的概念,以及简单的配置,让你能快速得搭建一个可用的 webpack ...

    QLQ 评论0 收藏0
  • 伪类与伪元素

    摘要:一伪类伪类包含两种状态伪类伪类和结构性伪类。状态伪类是基于元素当前状态进行选择的。二伪元素伪元素是对元素中的特定内容进行操作,而不是描述状态。 一、伪类 伪类包含两种:状态伪类(UI 伪类)和结构性伪类。 (1)状态伪类是基于元素当前状态进行选择的。 在与用户的交互过程中元素的状态是动态变化的,因此该元素会根据其状态呈现不同的样式。当元素处于某状态时会呈现该样式,而进入另一状态后,该样...

    ChanceWong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<