前言
两年前自己就开始学习 PostCSS ,但在开发中使用却不到一年。
没有使用的原因是觉得 PostCSS 插件太多,学习成本很高。
但在开发中实际使用后,觉得 PostCSS 还是有很大的便捷性,诸如自动补全浏览器前缀这一功能就节省了很多时间,把繁琐的工作交给了程序,心思都集中在代码逻辑上,会让开发的过程轻松不少。
PostCSS 是什么
PostCSS 是一个用 JavaScript 工具和插件转换 CSS 代码的工具。
- PostCSS 是处理 CSS 的一个插件体系;
- 可以对 CSS 进行各种不同的转换和处理;
- 把繁琐复杂的工作交由程序去处理;
- 把开发⼈人员解放出来。
PostCSS 如何使用
- PostCSS 一般不单独使用,而是与已有的构建工具进行集成;
- PostCSS 与主流的构建工具,如 Webpack、Grunt 和 Gulp 都可以进行集成;
- 完成集成之后,选择满足功能需求的 PostCSS 插件并进行配置。
PostCSS 常用插件
PostCSS 的插件数量很多,可以根据实际场景选择不同的插件。
PostCSS 有哪些插件
- 插件查询地址:www.postcss.parts/
- 常⽤用插件列列表:github.com/postcss/pos…
PostCSS 插件列举
- Autoprefixer:自动补全浏览器私有前缀
- precss:CSS 预处理(整合 Sass、LESS 或 Stylus 功能,语法基本和 Sass 的相同)
- postcss-import:通过 @import,整合多个 CSS 文件
- css-mqpacker:将相同的 CSS 媒体查询规则合并为一个
- cssnano:压缩 CSS 文件
- postcss-color-rgba-fallback:给 rgba 颜色创建降级方案(添加备用颜色)
- postcss-opacity:给 opacity 提供降级方案(给 IE 浏览器添加滤镜属性)
- node-pixrem:让 IE8 ⽀持 rem 单位
- postcss-pseudoelements:将伪元素的
::
转换为:
( IE8 不不⽀支持::
)
PostCSS 语法介绍
以下主要介绍 precss 插件的语法,precss 插件包含了 Autoprefixer 插件与 postcss-preset-env 插件。
Autoprefixer 插件语法
Autoprefixer:自动补全浏览器私有前缀,浏览器前缀可以参考 CanIUse 。
/*源代码*/
p{
transform: scale(1);
animation: ani 1s linear;
}
复制代码
/*编译后代码*/
p{
-webkit-transform:scale(1);
transform:scale(1);
-webkit-animation:ani 1s linear;
animation:ani 1s linear;
}
复制代码
postcss-preset-env 插件语法介绍
postcss-preset-env:支持现代的 css 语法。
-
重置标签所有属性
/*源代码*/ a{ all: initial; } 复制代码
/*编译后代码*/ a{ -webkit-animation:none 0s ease 0s 1 normal none running; -webkit-backface-visibility:visible; -o-border-image:none; …… } 复制代码
-
统一锚点各状态的样式
/*源代码*/ a:any-link{ background-color: yellow; } 复制代码
/*编译后代码*/ a:-webkit-any-link{ background-color:#ff0; } a:-moz-any-link{ background-color:#ff0; } a:link,a:visited{ background-color:#ff0; } 复制代码
-
自定义媒体查询
/*源代码*/ @custom-media --narrow-window (max-width: 30em); @media (--narrow-window) { } 复制代码
/*编译后代码*/ @media (max-width: 30em) { } 复制代码
-
自定义常量
/*源代码*/ :root{ --some-length: 32px; } p{ height: var(--some-length); width: var(--some-length); } 复制代码
/*编译后代码*/ :root{ --some-length:32px; } p{ height:32px; height:var(--some-length); width:32px; width:var(--some-length); } 复制代码
-
自定义选择器
/*源代码*/ @custom-selector :--heading h1, h2, h3, h4, h5, h6; :--heading { margin-block: 0; } 复制代码
/*编译后代码*/ h1,h2,h3,h4,h5,h6{ margin-top:0; margin-bottom:0; } 复制代码
-
支持嵌套规则
/*源代码*/ article{ &p{ color: #333; } } 复制代码
/*编译后代码*/ article p { color: #333; } 复制代码
-
overflow 简写
/*源代码*/ html{ overflow: hidden auto; } 复制代码
/*编译后代码*/ html{ overflow-x:hidden; overflow-y:auto; overflow:hidden auto; } 复制代码
precss 插件语法介绍
precss 支持类似sass语法,并支持未来语法,包含 postcss-preset-env 组件。
- 嵌套可以使用
&
符,把父选择器复制到子选择器中/*源代码*/ article { margin-top: 20px; &p{ color: #333; } } 复制代码
/*编译后代码*/ article{ margin-top:20px; } article p{ color:#333; } 复制代码
- 使用
$
符声明变量/*源代码*/ $text_color: #232323; $border_comn: 1px solid red; body{ color: $text_color; border: $border_comn; } 复制代码
/*编译后代码*/ body{ color:#232323; border:1px solid red; } 复制代码
- 用
@if
和@else
来控制循环/*源代码*/ $column_layout: 2; .column{ @if $column_layout == 2{ width: 50%; float: left; }@else{ width: 100%; } } 复制代码
/*编译后代码*/ .column{ width:50%; float:left; } 复制代码
- 用
@for
和@each
来循环- @for 循环:⽤用⼀一个计数器器变量量,来设置循环的周期
/*源代码*/ @for $i from 1 to 5{ p:nth-of-type($i){ margin-left: calc(100% / $i); } } 复制代码
/*编译后代码*/ p:first-of-type{ margin-left:100%; } p:nth-of-type(2){ margin-left:50%; } p:nth-of-type(3){ margin-left:33.33333%; } p:nth-of-type(4){ margin-left:25%; } p:nth-of-type(5){ margin-left:20%; } 复制代码
/*源代码*/ @for $count from 1 to 5 by 2 { .col-$count { width: $count%; } } 复制代码
/*编译后代码*/ .col-1{ width:1%; } .col-3{ width:3%; } .col-5{ width:5%; } 复制代码
- @each 循环:循环周期是⼀一个列列表,⽽而不不是数字
/*源代码*/ $social: twitter,facebook,youtube; @each $icon in ($social){ .icon-$(icon){ background: url('img/$(icon).png'); } } 复制代码
/*编译后代码*/ .icon-twitter{ background:url(img/twitter.png); } .icon-facebook{ background:url(img/facebook.png); } .icon-youtube{ background:url(img/youtube.png); } 复制代码
- @for 循环:⽤用⼀一个计数器器变量量,来设置循环的周期
- mixin 创建 css 模板函数
- 通过
@mixin mixin_name($arg1, $arg2) {...}
来声明 - 使用
@include mixin_name($arg1, $arg2)
来调用/*源代码*/ @mixin heading-text($color: #242424, $font-size: 4em) { color: $color; font-size: $font-size; } h1, h2, h3 { @include heading-text; } .some-heading-component>:first-child{ @include heading-text(#111111, 6em); } 复制代码
/*编译后代码*/ h1,h2,h3{ color:#242424; font-size:4em; } .some-heading-component>:first-child{ color:#111; font-size:6em; } 复制代码
- 通过
- 通过 @extend 创建 css 模板
/*源代码*/ %thick-border { border: thick dotted red; } .modal { @extend %thick-border; color: red; } 复制代码
/*编译后代码*/ .modal{ border:thick dotted red;color:red; } 复制代码
- @at-root 生成代码到根部
/*源代码*/ .parent { font-size: 20px; @at-root{ .child { font-size: 25px; } } } 复制代码
/*编译后代码*/ .child{ font-size:25px; } .parent{ font-size:20px; } 复制代码
- 直接引⽤用css属性的值,例如@color
/*源代码*/ .Test { margin-left: 20px; margin-right: @margin-left; color: red; background: @color url('test.png'); line-height: 1.5; font-size: @(line-height)em; } 复制代码
/*编译后代码*/ .Test{ margin-left:20px; margin-right:20px; color:red; background:red url(test.png); line-height:1.5; font-size:1.5em; } 复制代码
自定义 PostCSS 组件
一个 PostCSS 插件最基础的构成如下:
var postcss = require('postcss');
module.exports = postcss.plugin('PLUGIN_NAME', function (opts) {
opts = opts || {};
// 传⼊入配置相关的代码
return function (root, result) {
// 转化CSS 的功能代码
};
});
复制代码
然后按照不同的需求情况来决定是否引入第三方模块,是否有额外配置项,最后在包含 root,result 的匿名函数中进行最为核心的转换代码功能编写。
- root(css):也是整个 CSS 代码段,包含多个 rule;
- rule:包含一个 CSS class 范围内的代码段;
- nodes:代指 rule 中 {} 中间的多个 decl 部分;
- decl:单行 CSS ,即有属性与值的部分;
- prop value:键值对