CSS预处理器
作为一只有点追求的程序猿,你有木有经常在使用CSS定义样式的时候产生这样的想法——我能不能像写JS代码一样去组织CSS的代码,很遗憾的是纯CSS没法提供这样的编程式的开发流程给你使用,它更像是给设计狮进行页面的简单维护而生的;
基于这样的需求,于是CSS预处理器就应运而生。如同源代码需要通过通过编译才能变成二进制文件而后被计算机执行,CSS预处理器扮演的角色就是对CSS进行“预先编程”,然后编译成CSS文件;
给CSS预处理器下一个定义就是:CSS预处理器是一门编程语言,能够对页面样式进行设计然后再编译成CSS文件;
试想一下,你的CSS文件可以以编程的形式表现,必然使得设计样式的代码如同JS般代码更加具有:
- 开发友好;
- 组织性;
- 简洁性;
- 可维护性;
- 可读性;
目前常见的CSS预处理器包括:
- Sass(Scss)
- Less
- Stylus
本文主要以Less为例去分享一下CSS预处理的语法和实例;
配置Less
- 服务器端配置
# 安装
$ npm install -g less
# 编译
$ lessc style.less > style.css
# 压缩
$ lessc style.less -x > style.css
# 作为模块引用
var less = require('less');
less.render('./style.less',function(error,css){console.log(css)});
# 利用自动化构建工具,如gulp配置less;
$ npm install gulp -g
$ npm install gulp-less -S
//main.js
var gulp = require('gulp');
var less = require('gulp-less');
gulp.task('less',function(){
return gulp.src('./src/style.less')
.pipe(less())
.pipe(gulp.dest('../dist/css'))
})
$ gulp less;
- 客户端配置
//先将less文件引入<head>
<link rel="stylesheet/less" type="text/css" href="styles.less" />
//再将less.js引入<head>
<script src="less.js" type="text/javascript"></script>
可通过以下配置信息实时监测编译后的文件效果;
<script>less = { env: 'development'};</script><script src="less.js"></script><script>less.watch();</script>
Less的语言特性
1.变量
Less可以定义变量,,这个特性的好处是如果特定的属性值在经常用到可以不用重新赋值;通过变量进行运算更加符合编程思想;
//定义变量
@variable: value;
//引用
@variable | @{variable}
//简单引用
@bg-color: #000;
body{
background: @bg-color + #ccc;
#header{
background: darken(@bg-color,10%);
}
}
注意,当变量作为rule属性、rule属性部件、选择器、选择器部件和字符串拼接时,必须使用@{variable}
//rule属性
@bgc : background-color
.header{
@{bgc} : #ccc;
}
//rule属性部件
@color:color
.header{
background-@{color} :#ccc;
}
//选择器
@rule: .rule
@{rule}{
color: red;
}
//选择器部件
.header-@{rule}{
color: red;
}
//字符串拼接
@hello: 'hello';
@world: world;
.hi {
content: '@{hello}@{world}';
}
//less变量支持列表类型数据,通过extract(variable , index)获取指定下标的值,通过length(variable)获取列表类型变量的元素个数;
@colors : #fff, #ccc, #000;
.header{
color: extract(@colors,0);
font-size: 12px*length(@colors);
}
```
#####2.嵌套
Less的嵌套特性能够**减少CSS代码的冗余**;
```
.box{
>.item-1{
color:darken(#fff,5%);
}
.item-2{
color:darken(#fff,20%);
}
+ .item-3{
color:darken(#fff,40%)
}
}
```
```
//嵌套过程,如果需要重新返回上一级的父选择器,可以使用&;
.border{
border:1px solid #fff;
}
.parent{
.children{.border;}
&:hover{
color:red;
}
}
```
#####3. 混合
Less的混合特性能够在另个一类的规则集中引用定义好的规则集,从而实现**代码的复用性**;
```
.font-rule{
font-size: 30px;
text-align: center;
color:#fff;
line-height: 50px;
}
.item{
height: 50px;
background: lighten(@bg-color,40%);
.font-rule
}
```
mixin本质上相当于**函数**;
```
.change-bg-color(@color){
background: @color;
}
.box{
.item-1{
color:darken(#fff,5%);
}
.item-2{
color:darken(#fff,20%);
}
.item-3{
color:darken(#fff,40%);
.change-bg-color(pink)
}
}
```
```
//minxin内置两个对象@arguments和@reset,@arguments代表mixin的所有入参,而@reset代表mixin的入参数组;
.rule (@width,@height,@color,@font-size){
width: @width;
height: @height;
color:@color;
font-size:@font-size;
background: #aaa;
}
.border(@width,@style,@color){
border:@arguments;
}
.box{
.border(1px,solid,black);
.rule(100px,100px,#fff,20px);
}
```
**Less中的"条件语句"**
```
@true:true;
@false:false;
.box when(@true){
&::after{
display:block;
content:'hi';
color:#000;
}
}
.box when (@true) or (@false){
&:hover{
background: #fff;
}
}
//可结合以下运算符和内置函数一起使用
// =,>,>=,<=,< 关系运算符
// and、not、or(使用,号表示) 逻辑运算符
/* 类型判断函数 * iscolor * isnumber * isstring * iskeyword * isurl */
/* 单位判断函数 * ispixel * ispercentage * isem * isunit */
```
**Less中的“循环语句”**
```
.container(@i,@n) when ((@i) =< @n){
.item-@{i}{
height: 100px;
background: #000;
}
.container(@i+1)
}
.container(1,4);
```
---
Less中存在内置函数可供调用,这里重点提以下default();
> default():作用相当于条件语句的else
```
.container(@i) when('.item-@{i}' = '.item-1'){
width: 100px;
height: 100px;
background: #aaa;
.container(@i) when('.item-@{i}' = '.item-2'){
width: 100px;
height: 100px;
background: pink;
}
.container() when(default()){
width: 100px;
height: 100px;
background: blue;
}
div{.container();}
```
#####4.@import
> @import引入外部less文件;
less的@import提供6个配置选项(reference、inline、less、css、once、multiple)来改变引入文件的特性;
- @import (reference) 'path':less文件作为样式库供extend和minxin引用;
- @import (inline) 'path' :用于引入与less不兼容的css文件,通过inline配置告知编译器不对引入的文件进行编译处理,直接输出到最终输出;*注意:引入的文件和当前文件会被编译为一个样式样式*
- @import (less) 'path':引入less文件;
- @import (css) 'path' : 引入css文件,但*当前文件会输出一个样式文件,而被引入的文件自身为一个独立的样式文件*
- @import (once) 'path':对同一资源仅引入一次;
- @import (multiple) 'path' : 对同一资源引入多次;
#####5.继承extend()
- 两种继承方式
```
.bgc{
background:red;
}
.header:extend(.bgc){
color:white;
}
.footer{
&:extend(.bgc)
}
```
使用less的继承方法时要注意一下几点:
** 父选择器不支持变量形式**
```
@p1: .parent1;
@p2: .parent2;.
parent1{
height: 100px;
}
@{p2}{
height: 200px;
}
// 匹配失败
// 形式1,不支持以变量作入参
.son1:extend(@{p1}){}
// 形式2,不支持以变量作为选择器的规则集合
.son1:extend(.parent2){}
// 匹配成功
.son2:extend(.parent1){}
```
**media query影响继承的作用域**
```
// 非media query内的extend操作,将会继承所有media query中匹配的选择器样式
@media screen{
.parent{
height: 100px;
}
@media (min-width: 1023px){
.parent{
width: 200px;
}
}
}
.son:extend(.parent){}
//等价于
@media screen {
.parent,
.son {
height: 100px;
}
}
@media screen and (min-width: 1023px) {
.parent,
.son {
width: 200px;
}
}
```
```
//media query内的extend操作,仅能继承当前块的其他选择器样式;
.parent1{
height: 200px;
}
@media screen{
.parent1{
height: 100px;
}
// 无法继承子media query块的选择器样式
.son1:extend(.parent2){}
@media (min-width: 1023px){
// 继承父media query块的选择器样式
.son2:extend(.parent1){}
.parent2{
width: 200px;
}
}
}
```
---
参考资料:
- [Less文档](http://lesscss.cn/)
- [前端构建:Less入了个门](http://www.cnblogs.com/fsjohnhuang/p/4187675.html)
网友评论