less

CSS预处理器

CSS预处理器定义了一种新的语言,基本的思想是用一种专门的编程语言,开发者只需要使用这种语言进行编码工作,减少枯燥无味的CSS代码的编写过程的同时,它能让你的CSS具备更加简洁、适应性更强、可读性更加、层级关系更加明显、更易于代码的维护等诸多好处。

常用的有三门CSS预处理器语言:Sass、Less 、Stylus :

  • Sass 诞生于 2007 年,Ruby 编写,其语法功能都十分全面,可以说 它完全把 CSS 变成了一门编程语言。号称世界上最成熟、最稳定、最强大的专业级CSS扩展语言,默认使用 .sass 扩展名。
  • Less 诞生于 2009 年,受Sass的影响创建的一个开源项目。 它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充(引用于官网),默认使用 .less 扩展名。。
  • Stylus 诞生于 2010 年,是一个基于Node.js的CSS的预处理框架,其本质上做的事情与 Sass/LESS 等类似, 可以以近似脚本的方式去写CSS代码,创建健壮的、动态的、富有表现力的CSS,默认使用 .styl 的作为文件扩展名,支持多样性的CSS语法

安装引用

npm install -g less
lessc index.less index.css
或者
<link rel="stylesheet/less" type="text/css" href="index.less" />
<script src="less.js" type="text/javascript"></script>

语法特性

Variables(变量)

你可以把反复使用的css属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。以@开头定义变量,并且使用时直接键入@名称。

@themes: "../../src/themes";  //Import statements (导入语句)
@import "@{themes}/index.less"; //使用@import (reference)导入外部文件,但不会把导入的文件编译到最终输出中,只引用。

@primaryColor: #5B83AD;
@selector: #header;  //Selectors (选择器)
@nav: header;
@images: "../img";  //URLs
@property: height;  //Properties (属性)
@fnord:  "I am fnord.";  //Variable Names (变量名)
@var:  "fnord";

@{selector} {//变量名 必须使用大括号包裹
  color: @primaryColor;
}
.@{nav} {
  color: @primaryColor;
  background: url("@{images}/white-sand.png");
}
#@{nav} {
  color: @primaryColor;
  @{property}: 60px;
  &::after{
     content: @@var; //将@var替换为其值 content:@fnord;
   }
}

//编译后
#header {
  color: #5B83AD;
}
.nav{
  color: #5B83AD;
  background: url("../img/white-sand.png");
}
#nav {
  color: #5B83AD;
  height: 60px;
}
#nav::after{
    content: "I am fnord.";
}

变量运算:任何数值,颜色和变量都可以进行运算。

@base: 5%;
@filler: @base * 2;
@other: @base + @filler;
@base-color: #333;

color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

变量的延迟加载:变量是延迟加载的,在使用前不一定要预先声明。

.lazy-eval-scope {
  width: @var;
  @a: 9%;
}
@var: @a;
@a: 100%;

// 编译后
.lazy-eval-scope {
  width: 9%;
}
//在定义一个变量两次时,只会使用最后定义的变量,Less会从当前作用域中向上搜索。这个行为类似于CSS的定义中始终使用最后定义的属性值。

变量的作用域:Less 中的作用域与编程语言中的作用域概念非常相似。首先会在局部查找变量和混合,如果没找到,编译器就会在父作用域中查找,依次类推。

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}

Nested rules (嵌套规则)

它模仿了 HTML 的结构,父子节点关系一目了然,省去了大量的parent元素

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .clearfix {
    display: block;
    zoom: 1;
   //(& 表示当前选择器的父选择器)
    &:after {
      content: " ";
      display: block;
      font-size: 0;
      height: 0;
      clear: both;
      visibility: hidden;
    }
  }
}

// 编译后
#header {
  color: #5B83AD;
}
#header .navigation {
  font-size: 12px;
}
#header .clearfix {
  display: block;
  zoom: 1;
}
#header .clearfix:after {
  content: " ";
  display: block;
  font-size: 0;
  height: 0;
  clear: both;
  visibility: hidden;
}

Mixins (混合)

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
.marginTop10 {
   margin-top: 10px;
}
#menu a {
  color: #111;
  .bordered; // 等价于.bordered();
  .marginTop10() !important;
}

//在调用的混合集后面追加 !important 关键字,可以使混合集里面的所有属性都继承 !important:

// 编译后
#header {
  color: #5B83AD;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
  margin-top: 10px !important;
}

Namespaces (命名空间):如果你想要将属性混合到比较复杂的选择器中,你可以通过嵌套多层id或者class。

#outer {
  .inner {
    color: red;
  }
}
.c {
  #outer > .inner;
// 下面四种写法效果是一样的
// #outer > .inner;
// #outer > .inner();
// #outer.inner;
// #outer.inner();
}

Not outputting the mixin(不输出混合集):如果你想要创建一个混合集,但是却不想让它输出到你的样式中,你可以在混合集的名字后面加上一个括号。

.my-mixin {
  color: black;
}
.my-other-mixin() {
  background: white;
}
.class {
  .my-mixin;
  .my-other-mixin;
}
// 编译后
.my-mixin {
  color: black;
}
.class {
  color: black;
  background: white;
}

Selectors in mixins (带选择器的混合集):混合集不仅可以包含各种属性,而且可以包括各种选择器。

.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}
button {
  .my-hover-mixin();
}
// 编译后
button:hover {
  border: 1px solid red;
}

Parametric Mixins (带参数的混合):Less 可以使用默认参数,如果没有传参数,那么将使用默认参数。
@arguments在mixins内部有特殊意义,调用mixin时,它包含所有传入的参数。

.border(@a:10px,@b:50px,@c:30px,@color:#000){
   border:solid 1px @color;
   box-shadow: @arguments;//指代的是 全部参数
}
#main{
   .border(0px,5px,30px,red);//必须带着单位
}
#wrap{
  .border(0px);
}
#content{
  .border;//等价于 .border()
}
    
 // 编译后
#main{
  border:solid 1px red;
  box-shadow:0px 5px 30px red;
}
#wrap{
  border:solid 1px #000;
  box-shadow: 0px 50px 30px #000;
}
#content{
  border:solid 1px #000;
  box-shadow: 10px 50px 30px #000;
}
    

Mixin Guards:带条件的mixins,Less 没有 if else,可是它有 when

#card{
// and 运算符 ,相当于 与运算 &&,必须条件全部符合才会执行
  .border(@width,@color,@style) when (@width>100px) and(@color=#999){
    border:@style @color @width;
  }
// not 运算符,相当于 非运算 !,条件为 不符合才会执行
  .background(@color) when not (@color>=#222){
     background:@color;
  }
// , 逗号分隔符:相当于 或运算 ||,只要有一个符合条件就会执行
  .font(@size:20px) when (@size>50px) , (@size<100px){
     font-size: @size;
  }
}
#main{
  #card>.border(200px,#999,solid);
  #card .background(#111);
  #card > .font(40px);
}

// 编译后
#main{
  border:solid #999 200px;
  background:#111;
  font-size:40px;
}

Loops (循环)

在Less中,混合可以调用它自身。这样,当一个混合递归调用自己,再结合Guard表达式和模式匹配这两个特性,就可以写出循环结构。

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // 递归调用自身
  width: (10px * @counter); // 每次调用时产生的样式代码
}

div {
  .loop(5); // 调用循环
}
//编译后
div {
  width: 10px;
  width: 20px;
  width: 30px;
  width: 40px;
  width: 50px;
}

// 使用递归循环最常见的情况就是生成栅格系统的CSS:
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

// 编译后
.column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}

Extend (扩展)

extend是一个Less伪类,它会合并它所在的选择器和它所匹配的引用。

.inline {
  color: red;
  .a {
    width: 20px;
  }
}
nav ul {
  &:extend(.inline);
  &:extend(.inline .a);
}

// 编译后
.inline {
  color: red;
}
.inline  .a {
  width: 20px;
}
nav ul {
  color: red;
  width: 20px;
}

Extend syntax (扩展语法)
使用关键字all选择

.c:extend(.d all) {
  // 扩展".d"的所有实例,比如".x.d"或者".d.x"
}
.a.b.test,
.test.c {
  color: orange;
}
.test {
  &:hover {
    color: green;
  }
}

.replacement:extend(.test all) {}

// 编译后
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
  color: orange;
}
.test:hover,
.replacement:hover {
  color: green;
}

Functions (函数)

Less 提供了许多用于转换颜色,处理字符串和进行算术运算的函数。

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); //50%
  color: saturate(@base, 5%); //饱和度增加了 5%
  background-color: spin(lighten(@base, 25%), 8); //亮度增加了 25%,色相值增加 8
}
注释
/* 这种注释会被编译 */
@var: red;

// 这种注释不会被编译
@var: white;

创建一个demo

由于浏览器端使用时是使用ajax来拉取.less文件,因此直接在本机文件系统打开(即地址是file://开头)或者是有跨域的情况下会拉取不到.less文件,导致样式无法生效。所以启动一个本地服务器来进行:

npm i -D gulp gulp-connect
touch gulpfile.js

vim gulpfile.js

var gulp = require('gulp');
var connect = require('gulp-connect');

gulp.task('webserver', function () {
    connect.server({
        livereload: true,
        port: 2000
    });
});

gulp.task('default', ['webserver']);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容