less

变量(Variables

@nice-blue: #5B83AD;

@light-blue: @nice-blue + #111;

#header { color: @light-blue; }

编译为:

#header {

  color: #6c94be;

}

混合(Mixins

.bordered { border-top: dotted 1px black; border-bottom: solid 2px black; }

#menu a { color: #111; .bordered; }

.post a { color: red; .bordered; }

 

再举几个栗子:

.a, #b { color: red; }

.mixin-class { .a(); }

.mixin-id { #b(); }

注意其中的.a()#b(),.a#b来是一样的效果。两种等效。

经典应用

又想创造一个类又不想让他输出,只想让它被别的用的时候********后面加个()

.my-mixin { color: black; }

.my-other-mixin() { //注意这里多了个()是关键,表示不单独输出这个,但是其他的还是可 //以使用这个

background: white;

}

.class { .my-mixin; .my-other-mixin; }

输出结果:里面并不含 .my-other-mixin 这个单独的类

.my-mixin { color: black; }

.class { color: black; background: white; }

 

选择器中的插入混合

.my-hover-mixin() {

  &:hover { border: 1px solid red; }

}

button { .my-hover-mixin(); }

输出:

button:hover { border: 1px solid red; }

定义一个hover效果,在别的类中插入,就可以获得类的hover效果。

 

命名空间

如果您想要在一个更复杂的选择器中混合属性,您可以堆叠多个id或类。

#outer {

.inner { color: red; }

}

只想用.Inner

.c { #outer > .inner; }

大概意思就是你想用某个大的属性中的某个小的属性,就可以通过堆叠的方式来进行,类似css中的选择

有条件的类名

效果类似如下:

#namespace when (@mode=huge) {

.mixin() { /* */ }

}

#namespace {

.mixin() when (@mode=huge) { /* */ }

}

想要了解更多可以查看api文档

!important 关键字

用法如下:

.foo (@bg: #f5f5f5, @color: #900) {

  background: @bg;

  color: @color;

}

.unimportant {

  .foo();

}

.important {

  .foo() !important;

}

输出:

.unimportant {

  background: #f5f5f5;

  color: #900;

}

.important {

  background: #f5f5f5 !important;

  color: #900 !important;

}

传参的插入混合

定义一个:

.border-radius(@radius) {

-webkit-border-radius: @radius;

-moz-border-radius: @radius;

border-radius: @radius;

}

 

定义完了以后用法--->

#header {

.border-radius(4px);

}

.button {

.border-radius(6px);

}

定义的时候也可以给定默认值

.border-radius(@radius: 5px) {

-webkit-border-radius: @radius;

-moz-border-radius:

@radius; border-radius: @radius;

}

然后可以这么调用

#header { .border-radius; }

多个参数的插入和混合

.mixin(@color) {

  color-1: @color;

}

.mixin(@color; @padding: 2) {

  color-2: @color;

  padding-2: @padding;

}

.mixin(@color; @padding; @margin: 2) {

  color-3: @color;

  padding-3: @padding;

  margin: @margin @margin @margin @margin;

}

.some .selector div {

  .mixin(#008000);

}

输出:

.some .selector div {

  color-1: #008000;

  color-2: #008000;

  padding-2: 2;

}

这里有个问题: 为什么输出到color-2 当参数是两个的时候,从2输出到3,三个参数的时候只输出3.

 

多个参数也可以提前赋值

举个栗子:

 

.mixin(@color: black; @margin: 10px; @padding: 20px) {

color: @color;

margin: @margin;

padding: @padding;

}

.class1 {

.mixin(@margin: 20px; @color: #33acfe);

}

.class2 {

.mixin(#efca44; @padding: 40px);

}

可以看到赋值不用管顺序,而且可以先赋值

输出

.class1 {

color: #33acfe;

margin: 20px; padding: 20px;

}

.class2 {

color: #efca44;

margin: 10px;

padding: 40px;

}

参数数组变量@arguments

.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {

 -webkit-box-shadow: @arguments;

 -moz-box-shadow: @arguments;

 box-shadow: @arguments;

}

.big-block {

 .box-shadow(2px; 5px);//直接传入参数组

}

输出结果

.big-block {

 -webkit-box-shadow: 2px 5px 1px #000;

 -moz-box-shadow: 2px 5px 1px #000;

 box-shadow: 2px 5px 1px #000;

}

可变参数数量的使用

.mixin(...) {        // matches 0-N arguments

.mixin() {           // matches exactly 0 arguments

.mixin(@a: 1) {      // matches 0-1 arguments

.mixin(@a: 1; ...) { // matches 0-N arguments

.mixin(@a; ...) {    // matches 1-N arguments

或者:

.mixin(@a; @rest...) {

   // @rest is bound to arguments after @a

   // @arguments is bound to all arguments

}

通过以上都可以获得一个参数可变的声明类

根据传递的参数改变混合的行为(类似函数)

.mixin(@s; @color) { ... }

.class {

.mixin(@switch; #888);

}

定义.mixin

.mixin(dark; @color) {

 color: darken(@color, 10%);

}

.mixin(light; @color) {

  color: lighten(@color, 10%);

}

.mixin(@_; @color) {

  display: block;

}

如果我们运行

@switch: light;

.class { .mixin(@switch; #888); }

输出的结果会是

.class {

color: #a2a2a2; display: block;

 }

中间的判断过程大概是

第一个mixin定义不匹配,因为它期望第一个参数为dark

第二个mixin定义匹配,因为它期望第一个参数是light

第三个mixin定义匹配,因为它期望第一个参数都可以

也就是说参数匹配的才可以执行(完全的函数思路)

 

也可以通过参数数量来进行匹配

.mixin(@a) { color: @a; }

.mixin(@a; @b) { color: fade(@a; @b); }

传一个参数就匹配一个的,传两个参数就匹配两个的

 

类似函数的混合

mixin中定义的变量和mixin是可见的,可以在调用者的范围中使用。只有一个例外,如果调用者包含同名的变量(包含由另一个mixin调用定义的变量),则不会复制变量。只有在调用者本地范围内的变量才被保护。从父作用域继承的变量被重写。

.mixin() {

@width: 100%;

@height: 200px;

}

.caller {

.mixin();

width: @width;

height: @height;

}

输出结果

.caller {

width: 100%;

height: 200px;

}

调用完.mixin以后,里面的值会作为返回值返回,这就使得我们能像使用函数一样使用。

在来个栗子:

.average(@x, @y) {

 @average: ((@x + @y) / 2);

}

div {

 .average(16px, 50px); // "call" the mixin

 padding: @average; // use its "return" value

}

在调用方范围中直接定义的变量不能被覆盖。但是,在调用方的父范围中定义的变量不受保护,并且将被覆盖

举个栗子:

.mixin() {

  @size: in-mixin;

  @definedOnlyInMixin: in-mixin;

}

.class {

  margin: @size @definedOnlyInMixin;

  .mixin();

}

@size: globaly-defined-value; // 全局定义的  父级的不受保护

输出结果:  全局定义的在。Class内被局部的覆盖了

.class {

  margin: in-mixin in-mixin;

}

 

多层嵌套的依旧会作为返回值

.unlock(@value) { // 外部mixin

  .doSomething() { // 嵌套的mixin

    declaration: @value;

  }

}

#namespace {

  .unlock(5); // unlock doSomething mixin

  .doSomething(); //nested mixin was copied here and is usable(可用的)

}

 

输出:

#namespace {

  declaration: 5;

}

大概流程: .unlock(5) doSomething的@value 传了一个值

 .doSomething(); 又调用这个函数 并使用了返回值 declaration: @value;

 

 

嵌套(Nesting

#header { color: black; }

#header .navigation { font-size: 12px; }

#header .logo { width: 300px; }

可写为

#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; } }

 

.clearfix {

display: block; zoom: 1;

&:after { content: " ";

display: block; font-size: 0;

height: 0;

clear: both;

 visibility: hidden; }

 }

 

& represents the current selector parent  &表示的是当前选择的父级

 

运算(Operations

 

@conversion-1: 5cm + 10mm; // result is 6cm 

@conversion-2: 2 - 3cm - 5mm; // result is -1.5cm // conversion is impossible @incompatible-units: 2 + 5px - 3cm; // result is 4px // example with variables @base: 5%; @filler: @base * 2; // result is 10% 

@other: @base + @filler; // result is 15%

 

Escaping(中文是转义字符)

Escaping allows you to use any arbitrary string as property or variable value. Anything inside ~"anything" or ~'anything' is used as is with no changes except interpolation.

转义允许您使用任意字符串作为属性或变量值。~“任何东西任何东西~的任何东西除了插值之外没有任何变化。

@min768: ~"(min-width: 768px)";

.element {

  @media @min768 {

    font-size: 1.2rem;

  }

}

编译为:

@media (min-width: 768px) {

  .element {

    font-size: 1.2rem;

  }

}

 

函数(Functions

例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法:

@base: #f04615;

@width: 0.5;

.class {

 width: percentage(@width); // returns `50%`

 color: saturate(@base, 5%);

 

}

Namespaces and Accessors

(作用类似于封装)

#bundle() {

  .button {

    display: block;

    border: 1px solid black;

    background-color: grey;

    &:hover {

      background-color: white

    }

  }

  .tab { ... }

  .citation { ... }

}

可写为

#header a {

  color: orange;

  #bundle > .button;  // can also be written as #bundle.button

}

 

作用域(Scope

 

@var: red;

#page {

@var: white;

#header {

color: @var; // white

 }

 }

 

@var: red;

#page {

#header {

color: @var; // white

}

 @var: white;

 }

用距离最近的作用域内的值

 

注释(Comments

块注释和行注释都可以使用:

/* 一个块注释 * style comment! */ 

@var: red;

 // 这一行被注释掉了!

 @var: white;

 

导入(Importing

 

“导入”的工作方式和你预期的一样。你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉:

@import "library";

// library.less

@import "typo.css";

 

导入的顺序

less@import出现的位置是没有限制的,可以在进行中的位置进行导入

.foo { background: #900; }

@import "this-is-valid.less";

 

导入的时候还可以加一些参数进行处理

reference:使用较少的文件,但不要输出它。

inline:在输出中包含源文件,但不处理它。

less:无论文件扩展名如何,将文件视为一个更少的文件。

css:无论文件扩展名是什么,将文件作为css文件处理。

once:只包含一次文件(这是默认行为)

multiple:包含文件多次。

optional:在未找到文件时继续编译。

举个栗子:

@import (optional, reference) "foo.less";

具体每个参数的详细效果还得自己实验,看翻译看不出来 详细的英文原版在这里查找:

http://lesscss.cn/features/#import-options

 

 

 

 

安装less

命令行安装  (全局安装)

npm install less -g 

为了装逼或者信息更详细你可以后面加上版本号来安装特定版本的less

npm install less@2.7.1 -g

Node中开发安装也可以

npm i less --save-dev   (记住这个命令要在你所在的文件夹内的小黑框内输入)

会安装最新的版本并在你的 package.json的devDependencies  中增加版本和安装信息

 

lessc -v   查看你安装的版本

 

Less编译成css

 

 

官方栗子:

lessc [option option=parameter ...] <source> [destination]

实例

lessc bootstrap.less bootstrap.css

 

Less中的一些常见命令

Silent

消除错误,不再显示错误信息

lessc -s    lessc --silent

 

Version

查看版本信息

lessc -v

lessc --version

 

Help  

查看帮助信息

lessc --help

lessc -h

了解更多可以参考less options

 

浏览器中的使用

下载并引入两个关于lesscssjs文件

Js是给定的,css是需要用户自己编写的

下在地址https://github.com/less/less.js/archive/master.zip

<link rel="stylesheet/less" type="text/css" href="styles.less" />

引入的less文件会被解析成css文件供你的项目使用

<script src="less.js" type="text/javascript"></script>

 

设置选项

<script>

  less = {

env: "development",

async: false,

fileAsync: false,

poll: 1000,

functions: {},

dumpLineNumbers: "comments",

 relativeUrls: false,

rootpath: ":/a.com/" 

};

</script> 

<script src="less.js"></script>

 

在引入less之前可以设置一些选项参数和函数,这样初始化的时候就会统一受到这些参数的影响。

另外一种方式就是:

<script> 

less = {

env: "development" 

};

</script> 

<script src="less.js" data-env="development"></script>

 

另外一种方式:可以在scriptlink中用一种类似于属性的方式引入

<script src="less.js" data-poll="1000" data-relative-urls="false">

</script> 

<link data-dump-line-numbers="all" data-global-vars='{ "myvar": "#ddffee", "mystr": "\"quoted\"" }' rel="stylesheet/less" type="text/css" href="less/styles.less">

 

Extend(延伸扩大,就是获得别的类的值的基础上自己可以扩展)

Extend语法

Extend用法举例子

nav ul {

  &:extend(.inline);

background: blue;

}

.inline { color: red; }

 

编译后:

nav ul {

 background: blue;

 }

.inline,

 nav ul {

  color: red;

 }

可以看出nav ul 获得了inline 的值并在其基础上进行了扩展,而且nav ul 在使用时 inline还没有出现(参考作用域和lazyload的解释)。

Extend 两种语法进行:

第一种:

.a:extend(.b) {

}

第二种:

.a {

&:extend(.b);

}

进阶用法:

.c:extend(.d all) {

// 这种情况下会把所有的d 包含的全部复制获得 只要是卸载d 中的一切样式

}

.c:extend(.d) {

 // 这种情况就只会扩展只有 d的所有的样式

}

比如 .d{

.f{

}

}

d中含有f 当为all的时候就会把f也获取。

进阶用法2

.e:extend(.f) {}

.e:extend(.g) {}

//上面的写法太臃肿可以改为下面的 只用,分开即可

.e:extend(.f, .g) {}

选择器上的扩展

有如下的要求

必须在选择器后面扩展:

  pre:hover:extend(div pre).

选择器后面和extend前面是可以有空格的

pre:hover :extend(div pre).(hover后面有一个空格

可以实现多个扩展

pre:hover:extend(div pre):extend(.bucket tr) 

上面的写法和下面的是一样的结果

 pre:hover:extend(div pre, .bucket tr)

下面是错误的写法(extend必须在最后面的要求)

 pre:hover:extend(div pre).nth-child(odd

 

 

集合中的扩展

pre:hover,

.some-class {

&:extend(div pre);

}

相当于给每一个都进行了扩展

pre:hover:extend(div pre),

.some-class:extend(div pre) {

}

 

 

嵌套中的扩展

栗子:

.bucket {

  tr {

    color: blue;

  }

}

.some-class:extend(.bucket tr) {}

编译后

.bucket tr,.some-class {

  color: blue;

}

 

不明所以但是加了个&就不一样了这个&应该是一种用法

栗子:

.bucket {

  tr & {

    color: blue;

  }

}

.some-class:extend(tr .bucket) {}

编译后

tr .bucket,.some-class {

  color: blue;

}

 

 

扩展的准确性

.a.class,

 .class.a,

 .class > .a {

 color: blue;

 }

.test:extend(.class) {} // 这个不会匹配上面的任何一个

 

*.class { color: blue; }

.noStar:extend(.class) {}

输出结果

*.class { color: blue; }

//*.class .class的效果是一样的没有区别但是会导致扩展无法识别

顺序也会影响

link:hover:visited {

  color: blue;

}

.selector:extend(link:visited:hover) {} //顺序改变了extend不会识别

输出

link:hover:visited {

  color: blue;

}

Nth的效果

虽然css中的iN+3 N+3基本一样,但是extend却无法识别

:nth-child(1n+3) {

  color: blue;

}

.child:extend(:nth-child(n+3)) {}//换成了n+3 因此下面无法识别

输出:

nth-child(1n+3) {

  color: blue;

}

属性key-value值的效果

[title=identifier] {

  color: blue;

}

[title='identifier'] {

  color: blue;

}

[title="identifier"] {

  color: blue;

}

以上三种都是可以被识别的 三个的效果是一样的可以互通

.noQuote:extend([title=identifier]){}

.singleQuote:extend([title='identifier']) {}

.doubleQuote:extend([title="identifier"]) {}

输出

[title=identifier],.noQuote,.singleQuote,.doubleQuote {

  color: blue;

}

[title='identifier'],.noQuote,.singleQuote,.doubleQuote {

  color: blue;

}

[title="identifier"],.noQuote,.singleQuote,.doubleQuote {

  color: blue;

}

All 

进阶用法中已经介绍

Extend 不能识别含有变量的,它会自动忽略

@variable: .bucket;

@{variable} {

// interpolated selector color: blue; }

.some-class:extend(.bucket) {} // 什么都不会做,不会匹配

下面的额方式依然还是不会被识别

.bucket {

 color: blue;

}

.some-class:extend(@{variable}) {} // interpolated selector matches nothing @variable: .bucket;

 

媒体查询中的扩展

在媒体声明中写入的扩展应该只匹配同一媒体声明中的选择器:

@media print {

  .screenClass:extend(.selector) {} // 在媒体查询中扩展

  .selector { // 同一个媒体查询中的才会被匹配

    color: black;

  }

}

.selector { //这个不会被匹配

  color: red;

}

@media screen {

  .selector {  //不是同一个media也不会被匹配

    color: blue;

  }

}

输出:

@media print {

  .selector,

  .screenClass {

    color: black;

  }

}

.selector {

  color: red;

}

@media screen {

  .selector {

    color: blue;

  }

}

在媒体声明中写入的扩展不匹配嵌套中的选择器。

栗子:

@media screen {

  .screenClass:extend(.selector) {} // extend inside media

  @media (min-width: 1023px) {

    .selector {  // ruleset inside nested media - extend ignores it

      color: blue;

    }

  }

}

输出:

@media screen and (min-width: 1023px) {

  .selector { /* ruleset inside another nested media was ignored */

    color: blue;

  }

}

顶级扩展匹配所有内容,包括嵌套媒体中的选择器:不名所以,貌似是@media screen是全局的所以extend是可以用的

@media screen {

  .selector {  /* ruleset inside nested media - top level extend works */

    color: blue;

  }

  @media (min-width: 1023px) {

    .selector {  /* ruleset inside nested media - top level extend works */

      color: blue;

    }

  }

}

.topLevel:extend(.selector) {} /* top level extend matches everything */

输出:

@media screen {

  .selector,

  .topLevel { /* ruleset inside media was extended */

    color: blue;

  }

}

@media screen and (min-width: 1023px) {

  .selector,

  .topLevel { /* ruleset inside nested media was extended */

    color: blue;

  }

}

Duplication Detection重复检测

Currently there is no duplication detection.

栗子:

.alert-info,.widget {

  /* declarations */

}

.alert:extend(.alert-info, .widget) {}

输出

.alert-info,.widget,.alert,.alert {

  /* declarations */ 

//貌似是多了一个alert,但是在hbulideer中测试发现例子中的写法根本无法编译,直接报错了

}

Extend的使用情景

对于一些基础的类可以不用增加

举个栗子:

.animal {

 

color: white;

}

<a class="animal bear">Bear</a>

但是有这样一个标签不仅有动物的性值还有自己特殊的性值,因此你还需要给他再来个类

然后就变成这样

.animal {

 

color: white;

}

.bear { background-color: brown; }

这时你可以用less来进行:

<a class="bear">Bear</a> //只需要一个bear的类名就可以了

Less中的写法

.animal {

 background-color: black;

color: white;

}

.bear {

&:extend(.animal);

 

}

这种方式类似js中的原型和继承。

 

其他

此外less中还有循环结构 父级选择器等   循环是很厉害但是感觉没大用

http://lesscss.cn/features/#loops-feature