Tian Jiale's Blog

Less 笔记

less 是一种动态样式语言,属于 css 预处理器的范畴,它扩展了 CSS 语言, 增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展 LESS 既可以在 客户端 上运行 ,也可以借助 Node.js 在服务端运行。

less 的中文官网

官网地址

bootstrap 中 less 教程

教程地址

Less 编译工具

koala 官网: www.koala-app.com

Less 编译

  1. 用 koala 手动编译
  2. 借助 less 转 css 文件手动编译
  3. 利用打包工具编译

less 中的注释

以//开头的注释,不会被编译到 css 文件中

以/**/包裹的注释会被编译到 css 文件中

less 中的变量

LESS 中的变量为完全的 ‘常量’ ,所以只能定义一次。

使用@来申明一个变量:@pink:pink;

作为普通属性值

直接使用@pink

@nice-blue: #5b83ad;
@light-blue: @nice-blue + #111;
#header {
  color: @light-blue;
}
= > #header {
  color: #6c94be;
}

作为选择器和属性名

@{selector 的值}的形式

<div id="wrap"></div>
// less
@selector:#wrap;
@w:width;
@{selector}{
    @{w}:100px;
    height: 300px;
    border: 1px solid;
}
// 编译为css后
#wrap{
    width:100px;
    height:300px;
    border:1px solid;
}

作为 URL

@{url}

// less
@url: '../img/zdy.jpg';
#wrap {
  width: 100px;
  height: 100px;
  background: url('@{url}');
  // 也可以将url作为变量,写成下面形式
  // background: url(@url);
}
// 编译为css后
#wrap {
  width: 100px;
  height: 100px;
  background: url('../img/zdy.jpg');
}

变量的延迟加载

// less
@var: 0;
.class {
  @var: 1;
  .brass {
    @var: 2;
    three: @var; //3
    @var: 3;
  }
  one: @var; //1
}
// 编译为css后
.class {
  one: 1;
}
.class .brass {
  three: 3;
}

less 作用域

首先会从本地查找变量或者混合模块,如果没找到的话会去父级作用域中查找,直到找到为止.

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

less 中的嵌套规则

基本嵌套规则

// html页面:
<ul id="list">
  <li>
    <a href="javascript:;">a1</a>
    <span>b1</span>
  </li>
</ul>

// less嵌套写法:
#list {
  list-style: none;
  line-height: 30px;
  width: 300px;
  background: pink;
  margin: 0 auto;
  li {
    height: 30px;
  }
  a {
    float: left;
    /*&代表父级*/
    &:hover {
      color: red;
    }
  }
  span {
    float: right;
  }
}

&的使用(&代表父级)

如果想写串联选择器,而不是写后代选择器,就可以用到&了。这点对伪类尤其有用如 :hover 和 :focus.

less 中的混合

混合就是将一系列属性从一个规则集引入到另一个规则集的方式

任何 CSS class, id 或者 元素 属性集都可以以同样的方式引入.

以下测试,html 模板均为

// html
<div id="box1">box1</div>

普通混合

会将混合内容输出到 css 文件中

// less
.juzhong {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}
#box1 {
  width: 100px;
  height: 100px;
  background: pink;
  .juzhong;
}

// 编译为css后
.juzhong {
  // 会将混合内容输出到css文件中
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}
#box1 {
  width: 100px;
  height: 100px;
  background: pink;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}

不带输出的混合

加()后就不会在 css 中输出混合内容了

// less
.juzhong() {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}
#box1 {
  width: 100px;
  height: 100px;
  background: pink;
  .juzhong;
}

// 编译为css后
#box1 {
  width: 100px;
  height: 100px;
  background: pink;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}

带参数的混合

// less
.juzhong(@w,@h,@c) {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: @w;
  height: @h;
  background: @c;
}

#box1 {
  .juzhong(100px,100px,pink);
  z-index: 1;
}

// 编译为css后
#box1 {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: 100px;
  height: 100px;
  background: #ffc0cb;
  z-index: 1;
}

带参数并且有默认值的混合

// less
.juzhong(@w:100px,@h:100px,@c:pink) {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: @w;
  height: @h;
  background: @c;
}

#box1 {
  .juzhong;
  z-index: 1;
}

// 编译为css后
#box1 {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: 100px;
  height: 100px;
  background: #ffc0cb;
  z-index: 1;
}

带多个参数的混合

带参数并且有默认值的混合

形参和实参

命名参数就是引用 mixin 时可以通过参数名称而不是参数的位置来为 mixin 提供参数值。

任何参数都已通过它的名称来引用,这样就不必按照任意特定的顺序来使用

// less
.juzhong(@w:100px,@h:100px,@c:pink) {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: @w;
  height: @h;
  background: @c;
}
#box1 {
  // 引入混合时可以改变参数位置
  .juzhong(@h:200px;@c:deeppink;);
}

// 编译为css后
#box1 {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
  width: 100px;
  height: 200px;
  background: #ff1493;
}

匹配模式

根据传入的参数来改变混合的默认呈现。

// less
/*向上的三角*/
.triangle(top,@w:10px,@c:pink) {
  border-width: @w;
  border-color: transparent transparent @c transparent;
  border-style: dashed dashed solid dashed;
}

/*向下的三角*/
.triangle(bottom,@w:10px,@c:pink) {
  border-width: @w;
  border-color: @c transparent transparent transparent;
  border-style: solid dashed dashed dashed;
}

/*向左的三角*/
.triangle(left,@w:10px,@c:pink) {
  border-width: @w;
  border-color: transparent @c transparent transparent;
  border-style: dashed solid dashed dashed;
}

/*向右的三角*/
.triangle(right,@w:10px,@c:pink) {
  border-width: @w;
  border-color: transparent transparent transparent @c;
  border-style: dashed dashed dashed solid;
}

.triangle(@_,@w:10px,@c:pink) {
  width: 0;
  height: 0;
  overflow: hidden;
}

#box1 {
  // 向上三角图案
  .triangle(top,50px,deeppink);
}

// 编译为css后
#box1 {
  border-width: 50px;
  border-color: transparent transparent #ff1493 transparent;
  border-style: dashed dashed solid dashed;
  width: 0;
  height: 0;
  overflow: hidden;
}

导引表达式

当我们想根据表达式进行匹配,而非根据值和参数匹配时,导引就显得非常有用。如果你对函数式编程非常熟悉,那么你很可能已经使用过导引。

为了尽可能地保留 CSS 的可声明性,LESS 通过导引混合而非 if/else 语句来实现条件判断,因为前者已在@media query 特性中被定义。

从该例开始

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}

when 关键字用以定义一个导引序列(此例只有一个导引)。接下来我们运行下列代码

.class1 {
  .mixin(#ddd);
}
.class2 {
  .mixin(#555);
}

就会得到

.class1 {
  background-color: black;
  color: #ddd;
}
.class2 {
  background-color: white;
  color: #555;
}

导引中可用的全部比较运算有: > >= = =< <。此外,关键字 true 只表示布尔真值,除去关键字 true 以外的值都被视为布尔假,下面两个混合是相同的

.truth (@a) when (@a) {
  ...;
}
.truth (@a) when (@a = true) {
  ...;
}

导引序列使用逗号‘,’—分割,当且仅当所有条件都符合时,才会被视为匹配成功。

.mixin (@a) when (@a > 10), (@a < -10) {
  ...;
}

导引可以无参数,也可以对参数进行比较运算

@media: mobile;

.mixin (@a) when (@media = mobile) {
  ...;
}
.mixin (@a) when (@media = desktop) {
  ...;
}

.max (@a, @b) when (@a > @b) {
  width: @a;
}
.max (@a, @b) when (@a < @b) {
  width: @b;
}

最后,如果想基于值的类型进行匹配,我们就可以使用 is*函式

.mixin (@a, @b: 0) when (isnumber(@b)) { ... }
.mixin (@a, @b: black) when (iscolor(@b)) { ... }

// 下面就是常见的检测函式:
iscolor
isnumber
isstring
iskeyword
isurl
// 如果你想判断一个值是纯数字,还是某个单位量,可以使用下列函式
ispixel
ispercentage
isem

最后再补充一点,在导引序列中可以使用 and 关键字实现与条件,使用 not 关键字实现或条件。

arguments 变量

@arguments 包含了所有传递进来的参数. 如果你不想单独处理每一个参数的话就可以像这样写

.border(@w:10px,@style:solid,@c:deeppink) {
  border: @arguments;
}

less 运算

任何数字、颜色或者变量都可以参与运算

在 less 中可以进行加减乘除的运算

括号也同样允许使用

Color 函数

lighten(@color, 10%);      // 返回颜色比@color浅10%的颜色
darken(@color, 10%);       //返回颜色比@color深10%的颜色

saturate(@color, 10%);      // 返回饱和比比@color深10%的颜色
desaturate(@color, 10%);    // 返回饱和比比@color浅10%的颜色

fadein(@color, 10%);       // 返回颜色不透明度是@color10%的颜色
fadeout(@color, 10%);      // 返回颜色透明度是@color10%的颜色
fade(@color, 50%);        // 返回透明度是@color50%的颜色

spin(@color, 10);         // 颜色比@color大10的色调
spin(@color, -10);        // 颜色比@color小10的色调
mix(@color1, @color2);      // 返回@color1与@color2的混合值

Math 函数:

round(1.67); //四舍五入 returns `2`
ceil(2.4); // returns `3`
floor(2.6); // returns `2`
percentage(0.5); // returns `50%`

less 避免编译

有时候我们需要输出一些不正确的 CSS 语法或者使用一些 LESS 不认识的专有语法.

要输出这样的值我们可以在字符串前加上一个 ~

.class {
    filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()";
}
// 我们可以将要避免编译的值用 “”包含起来,输出结果为:
.class {
    filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
}

less 继承

性能比混合高

灵活度比混合低

extend(继承的类 all)

// less
.common:hover {
  background: pink;
}
.common {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}
.juzhong(@w:100px,@h:100px,@c:pink) {
  &:extend(.common all);
  width: @w;
  height: @h;
  background: @c;
}
#box1 {
  .juzhong();
  z-index: 1;
}

// 编译为css后
.common:hover {
  background: pink;
}
.common {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}
.juzhong(@w:100px,@h:100px,@c:pink) {
  &:extend(.common all);
  width: @w;
  height: @h;
  background: @c;
}
#box1 {
  .juzhong();
  z-index: 1;
}

命名空间

有时候,你可能为了更好组织 CSS 或者单纯是为了更好的封装,将一些变量或者混合模块打包起来

你可以像下面这样在#bundle 中定义一些属性集之后可以重复使用

#bundle {
  .button () {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover {
      background-color: white;
    }
  }
  .tab {
    ...;
  }
  .citation {
    ...;
  }
}
// 只需要在 #header a中像这样引入 .button
#header a {
  color: orange;
  #bundle > .button;
}

混合与继承区别

混合:就是将一系列属性从一个规则集引入到另一个规则集的方式,任何 CSS class, id 或者元素 属性集都可以以同样的方式引入。可带可不带参数,编译后相当于 ctrl c +ctrl v

继承:不能带参数,性能比混合高,灵活度比混合低。编译后再 css 中会将选择器组合在一起,代码减少。

JavaScript 表达式

慎用,测试报错

JavaScript 表达式也可以在.less 文件中使用. 可以通过反引号的方式使用:

@var: ` 'hello' .toUpperCase() + '!' `;
// 输出
@var: 'HELLO!';

// 注意你也可以同时使用字符串插值和避免编译
@str: 'hello';
@var: ~` '@{str}' .toUpperCase() + '!' `;

// 输出
@var: HELLO!;

// 它也可以访问JavaScript环境:
@height: `document.body.clientHeight`;

// 如果你想将一个JavaScript字符串解析成16进制的颜色值, 你可以使用 color 函数
@color: color(`window.colors.baseColor`);
@darkcolor: darken(@color, 10%);