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。
解决全局 CSS 的问题
postcss-use
允许你在 CSS 里明确地设置 PostCSS 插件,并且只在当前文件执行它们。postcss-modules
和react-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
] 添加并拓展了大量的缩写属性。
图片和字体
postcss-assets
可以插入图片尺寸和内联文件。postcss-sprites
能生成雪碧图。font-magician
生成所有在 CSS 里需要的@font-face
规则。postcss-inline-svg
允许你内联 SVG 并定制它的样式。postcss-write-svg
允许你在 CSS 里写简单的 SVG。
提示器(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的强大之处
- 在你的构建工具中找到postcss对应的扩展并添加。
- 查找你所需要的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兼容性
转换后 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就好啦