一:看过阮一峰大大介绍react的一篇文章中提到Postcss,甚是感兴趣,趁着项目空余小小研究了一下。那么到底Postcss到底是啥,能干啥呢??
现如今各种插件和工具多的数不胜数,比如gulp、grunt、webpack,less、scss等也都有对应其工具的相应插件,还有合并、压缩、浏览器自动刷新等实用插件,那Postcss存在的意义是什么呢?
模块化?!如果你的项目用的webpack或者是gulp,那么相应的要安装一堆处理各种文件的插件。Postcss可以说就是将你项目中所有处理css的插件进行了一个二次封装,让你基于Postcss这个平台来完成,用Postcss它独有的一套体系来处理项目中的css文件。也就是说如果你的项目中想使用Postcss,想感受Postcss的独特魅力,那么less、scss、clean-css等处理css的插件全部替换成Postcss其独特的插件就行了。
那么好,知道了Postcss是个什么鬼,来认识一下最出名(最实用)的插件autoprefixer
autoprefixer是让你可以偷懒的神器,如果你的项目是PC端的,并且产品大大或者项目经理大大要你兼容IE8~9,是不是很头疼。别怕,用了autoprefixer,写正常的标准css就好了,autoprefixer会自动帮你添加浏览器前缀的,哈哈。
Postcss还有许多功能,压缩合并它都可以,只要你感兴趣,完全可以运用到项目当中(不建议,当然如果你愿意折腾,请随意)。
不废话,上代码。
任务思路:添加浏览器前缀->编译css4->合并所有css文件->压缩处理好的css->移动至目标文件夹(实时监测css这个task)
gulp.task('css', function () {
gulp.src(['./src/css/*.css'])
.pipe(changed('dist/css', {hasChanged: changed.compareSha1Digest}))
.pipe(postCss([
autoprefixer({
browsers: ['last 4 version','Android >= 4.0'],//添加浏览器最近的四个版本需要的前缀,兼容安卓4.0以上版本
cascade: false,//是否美化属性,默认true
remove: true//移除不必要的前缀
}), cssNext()]))
.pipe(concat('main.css'))
.pipe(cleanCSS())
.pipe(gulp.dest('dist/css'))
.pipe(browserSync.reload({stream:true}));
});
你需要安装的有gulp、gulp-concat、gulp-postcss、autoprefixer、gulp-clean-css、gulp-changed、cssnext、browser-sync。
2017.6.19更新:不建议使用cssnext,css文件不支持@、$等符号,less和scss本身对于这些符号有自己的定义。cssnext依赖于autoprefixer,css4的属性需要添加浏览器前缀,并且cssnext实现的功能以后浏览器会怎么具体实现还存疑,没有实用价值。为了项目稳定,建议大家了解一下就好。二-11已经被主流浏览器支持,实测ie和360不行
如果不会用gulp和browser-sync可以去我的上一篇文章Gulp编译、合并、压缩,以及Browsersync实时刷新教程先学习一下。
二:上文提到了还未提案的css4、接下来介绍一下css4的新特性都有哪些?(习惯之后会很强大,cssnext支持的css4点击查看)
1、父元素选择器:$div>span
例:.wrap>$div>span{color:red;} 此时样式会落在带有$的div身上
例2:$ol>li:only-child{list-style:none;} 此时样式会落在只有一个li子元素的ol身上。
2、链接地址伪类:分割线//// :any-link(用于所有链接) :local-link(用于站内链接)
3、文本伪类:分割线//// :dir(ltr)从左到右 :dir(rtl)从右到左
例:p:dir(rtl){font-size:20px;} 将会渲染成字体大小为20px,文本排列方向从右向左的一行文字。
4、组合映射选择器:分割线//// :matches()
例:p:matches( :first-child , .main ){ color: red; } 结果 p:first-child , p.main{ color: red; }
例2:label:matches(:hover,:focus) input{box-shadow:0px 0px 10px red;} 当label获取焦点或者hover时,相对应的input会被高亮。对应关系当然是for和id了。
5、ID属性匹配
例:li:hover /data-type/ p{background-color:yellow;} 当li的data-type属性与p的id属性值相同时且当li处于hover状态下,对应的p会高亮。
6、wrap-flow:both;文字会在元素的四周包围。
7、围绕图形排列shape,仅在浮动元素上设置会生效
例:.shape{float:left;shape-outside:circle(50%)} 此时文字会在图片的周围按照图片的轮廓曲线排列
8、包含元素选择器 :has
例:table:has(tr:nth-of-type(11)){background-color:red} 若table元素内有超过10个tr,样式生效。
例2:div:has(p:nth-child(28)) 若div内的第28个元素为p,该div被选中
9、不包含元素选择器 :not
例:a:not(href*=['baidu']) 这样会选择所有链接中不包含baidu的链接
例2:div:not([class|='W_content'],:has(img)) 将会选中所有class不是以W_content开头或W_content_开头并且子元素没有img的div
10、块级样式scoped
例:此时style内的样式仅在div内部生效,即内部文字会变成红色
外部文字
内部文字
11、var()定义变量:定义变量只能在:root里面定义,定义变量的方法类似less和scss,因为@和$已经被less和scss占用了,所以使用‘--’作为变量的标识,使用var()调用
:root { --mainColor: red; --commonColor: green; --fontSize: 1rem; }
a { color: var(--commonColor); background-color: var(--mainColor); }
结果:a{ color:green; background-color:red; }
12、定义代码块@apply:在:root内定义,标识符是 ' -- ' ,@apply调用
:root{ --centered{ display:flex; align-items:center; justify-content:center; } } .centered{ @apply --contered; }
结果:.centered{ display:flex; align-items:center; justify-content:center; }
13、calc函数
例:.wrap{background-position:calc(100%-25px) calc(100%-25px)} 当你不知道容器的宽和高的时候,calc函数可以将背景图片定位到距离右下角25px的位置
例2:body{ font-size: calc( var( --fontSize ) * 2 ); } 结果: body{ font-size: 2rem; }
14、blackness:用于颜色,向黑色加深。
例:a{ color:color(red blackness(10%)); } 结果:a{ color: rgb(230, 0, 0) } //颜色加深了一点
例2:a{ color:color(red blackness(80%)); } 结果:a{ color: rgb(51, 0, 0); } //已经很接近黑色了
15、alpha:用与颜色,用更清晰的方式改变透明度,rgba中的a
例:a{ color: color(red alpha(-50%)); } 结果:a{ color: color: rgba(255, 0, 0, 0.5); }
16、gray():灰度,值越大颜色越浅
例:a{ color: gray(10); } 结果:a{ color:rgb(10,10,10); } //特别深的灰色,看起来像黑色
例2:a{ color: gray(200); } 结果:a{ color:rgb(200,200,200); } //特别浅的灰色,看起来像银色
三:css4封装的功能非常强大,目前这些草稿还未完全定稿,还有变化的可能,也许还会有许多新属性发布。当css4正式提案时,可能就是我放弃less和scss的时候到了,因为less或者scss与css4有些操作符是一样的,这会产生冲突,例如@、$。还有一些复杂的属性和选择器浏览器还不能支持。