CSS工程方案--Less、Sass、PostCss、Css in Js

965 阅读2分钟

一、Less和Sass/Scss(让css编写得像编程语言一样)

  1. Less介绍(变量使用@符号):less.bootcss.com/
 @width: 10px;
 @height:@width + 10px;
 #header { width: @width; height: @height; }
  1. Sass/Scss(变量使用$符号)介绍:sass-lang.com/guide

Sass的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass里面,因此sass语法进行了改良,Sass 3就变成了Scss(sassy css)。与原来的语法兼容,只是用{}取代了原来的缩进。

(1) Sass语法:

$font-stack: Helvetica, sans-serif //定义变量
$primary-color: #333 //定义变量
body
  font: 100% $font-stack
  color: $primary-color

(2) SCSS 语法:

$font-stark Helvetica, sans-serif;
$primary-color: #333;
body {
  font: 100% $font-stack;
  color: $primary-color;
}
  1. Less和Sass(SCSS)对比

共同点:

  • 支持嵌套Nesting、变量Variables、混合Mixins、运算Operators等
  • 需要预编译(通过webpack等编译工具)

不同点:

  • LESS环境(基于js,可以在客户端处理,也可以在node服务端使用);Sass(基于Ruby,需要在服务端处理)

less可以在浏览器中使用,如下所示:

<link rel="stylesheet/less" type="text/css" href="styles.less" /> 
<script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
  • 技术热点:国内前端团队使用LESS的同学会略多于Sass;就国外讨论的热度来说,Sass优于LESS

参考对比:developer.aliyun.com/article/847…

二、Css moudules(主要用于解决classname冲突的问题)

CSS Modules 提供各种插件,支持不同的构建工具。本文使用的是 Webpack 的css-loader插件,因为它对 CSS Modules 的支持最好,而且很容易使用。

下面是这个示例的webpack.config.js:

module.exports = {
  entry: __dirname + '/index.js',
  output: {
    publicPath: '/',
    filename: './bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'stage-0', 'react']
        }
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[local]--[hash:base64:5]',
                // webpack建议开发环境使用 '[path][name]__[local]'
                // 生产环境使用 '[hash:base64]'
              },
            },
          },
        ],
      },
    ]
  }
};
import React from 'react';
import style from './App.css';

export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

// 编译为
<h1 class="title--3zyde4l1yATCOkgn-DBWEL">
  Hello World
</h1>
// App.css
.title {
  color: red;
}
// 编译为
.title--3zyde4l1yATCOkgn-DBWEL {
  color: red;
}

参考链接:www.ruanyifeng.com/blog/2016/0…

三、PostCSS( CSS界的babel)

从其名字 postcss 可以看出早期是被当做后处理器的。也就是处理less/sass 编译后的 css。最常用的插件就是 autoprefixer,根据浏览器版本添加兼容前缀。

// 输入
:fullscreen {
}
// 输出
:-webkit-full-screen {
}
:-ms-fullscreen {
}
:fullscreen {
}

css工程化的流程图:

image.png

postcss的原理:

  • 将 CSS 字符串生成 Tokens
  • 将 Tokens 通过规则生成 AST 树
  • 将 AST 树传给插件进行处理
  • 将处理后的 AST 树生成新的css资源(包括css字符串、sourceMap等)

image.png

参考链接:juejin.cn/post/696436…

四、原生css的进展

  1. 声明变量的时候,变量名前面要加两根连词线(--)。

同一个 CSS 变量,可以在多个选择器内声明。读取的时候,优先级最高的声明生效。这与 CSS 的"层叠"(cascade)规则是一致的。

参考链接-css变量:www.ruanyifeng.com/blog/2017/0…

body {
  --foo: #7F583F;
  --bar: #F7EFD2;
}
  1. 读取

var()函数用于读取变量。

a {
  color: var(--foo);
  text-decoration-color: var(--bar);
}
  1. js可以获取并处理css变量

JavaScript 操作 CSS 变量的写法如下。

// 设置变量
document.body.style.setProperty('--primary', '#7F583F');
// 读取变量
document.body.style.getPropertyValue('--primary').trim();
// '#7F583F'
// 删除变量
document.body.style.removeProperty('--primary');

五、Css in js

你可能会问,它们与"CSS 预处理器"(比如 Less 和 Sass,包括 PostCSS)有什么区别?回答是 CSS in JS 使用 JavaScript 的语法,是 JavaScript 脚本的一部分,不用从头学习一套专用的 API,也不会多一道编译步骤

Ant Design 5.0 就使用了Css in js(代替Less和Css变量),让站点主题的变化更加灵活。

/** @jsx jsx */
import { jsx } from '@emotion/react'

let SomeComponent = props => {
  return (
    <div
      css={{
        color: 'hotpink'
      }}
      {...props}
    />
  )
}

参考链接:www.ruanyifeng.com/blog/2017/0…

六、延伸话题

Tailwind CSS是一个新兴的思路,借鉴了Bootstrap的栅格系统,并且利用了webpack等编译工具,支持了更加灵活的样式自定义需求。

将在下一个篇章展开写写。