概述
作为一种 CSS 扩展, Less 不仅向后兼容 CSS, 它还使用现有的 CSS 语法新增了额外的特性. 这使得学习 Less 更轻松, 一旦有任何问题,可以随时退回使用标准的 CSS.
Variables (变量)
- 管理重复值
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
- 除了使用变量管理值,还可以用在其他地方,例如选择器,属性名,url,@import语句中
//选择器
@mySelector : banner;
.@{mySelector}{
font-weight: bold;
line-height: 40px;
margin: 0 auto;
}
//url
@images: "../img";
//属性
@property:color;
.widget{
@{property}:#0ee;
background-@{property}:#999
}
//使用变量定义变量名
@fnord:"I am fnord";
@var :"fnord";
content:@@var;
//变量不一定要提前申明
.lazy-eval{
width:@var;
}
@var :@a;
@a:9%
//变量先在当前作用域查找,没有再去往上一级查找
@var:0;
.class{
@var: 1;
.brass {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
//编译为
.class {
one:1;
}
.class .brass{
three:3;
}
Extend (扩展)
- 不同选择器公用相同的样式,避免添加基础类
nav ul {
&:extend(.inline);
background: blue;
}
//编译为
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
- 规则集内的扩展
pre:hover,
.some-class {
&:extend(div pre);
}
//与下面的写法相同
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
- 扩展多个类,使用逗号分割
.e:extend(.f) {}
.e:extend(.g) {}
//上面的代码与下面做的事情一样
.e:extend(.f, .g) {}
- 编写在media声明内的extend也应该只匹配同一media声明内的选择器
@media print {
.screenClass:extend(.selector) {} // media内的extend
.selector { // 这个会匹配到-因为在同一的media内
color: black;
}
}
.selector { // 定义样式表中的规则 - extend会忽略它
color: red;
}
@media screen {
.selector { // 另一个media声明内的规则 - extend也会忽略它
color: blue;
}
}
- 编写在media声明内的extend不会匹配嵌套声明内的选择器
@media screen{
.screenClass:extend(.selector){}
@media (min-width:1023px){
.selector{color:blue};//嵌套media内的规则-extend会忽视它
}
}
- 顶级extend匹配一切,包括media嵌套内的选择器
@media screen {
.selector { /* media嵌套内的规则 - 顶级extend正常工作 */
color: blue;
}
@media (min-width: 1023px) {
.selector { /* media嵌套内的规则 - 顶级extend正常工作 */
color: blue;
}
}
}
.topLevel:extend(.selector) {} /* 顶级extend匹配一切 */
Mixins (混合)
- 不同的选择器之间可以相互调用,调用时,括号可加可不加
.a, #b {
color: red;
}
.mixin-class {
.a();
}
.mixin-id {
#b();
}
混合集不仅可以包含各种属性,还可以包括各种选择器
.my-hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.my-hover-mixin();
}
(命名空间 ) 可以将属性嵌套到比较复杂的选择器中,可以嵌套id或class
#outer {
.inner {
color: red;
}
}
.c {
#outer > .inner; //调用时建议使用这种方式,当然>是可选的
}
// 下面四种写法效果是一样的
#outer > .inner;
#outer > .inner();
#outer.inner;
#outer.inner();
//把混合集放到一个id选择器里面,这样可以确保它(这个混合集)不会跟其他的库冲突。
- 调用的混合集后面追加 !important 关键字,可以使混合集里面的所有属性都继承 !important:
.foo{
color:#333;
background:#555
}
.important{
.foo() !important ;
}
//结果为:
.important {
background: #555 !important;
color: #333 !important;
}
- 带参数的混合
.border-radius(@radius:5px) {//可以给参数设置初始值
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
//设置初始值后就可以像这样调用它
#header{
.border-radius
}
可以使用不接受参数的混合 ,如果想在输出的CSS中隐藏规则集,但又想使用规则集中的属性,则这个特性很有用
.wrap() {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}
pre { .wrap }
//输出
pre {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}
- 带多个参数的mixins
.mixin(@color; @padding; @margin: 2) {
color-3: @color;
padding-3: @padding;
margin: @margin @margin @margin @margin;
}
.some .selector div {
.mixin(#008000);
}
//注:任何参数都已通过它的名称来引用,这样就不必按照任意特定的顺序来使用参数
- 多个参数统一设置还可以使用@arguments 变量
.transition(@property:all,@duration;@timing-function;@delay){
-webkit-transition:@property @duration @timing-function @delay;
-moz-transition:@property @duration @timing-function @delay;
-ms-transition:@property @duration @timing-function @delay;
-o-transition:@property @duration @timing-function @delay;
transition:@property @duration @timing-function @delay;
}
//上面可以简写成如下
.transition(@property:all,@duration;@timing-function;@delay){
-webkit-transition:@arguments;
-moz-transition:@arguments;
-ms-transition:@arguments;
-o-transition:@arguments;
transition:@arguments;
}
- 接收数量不定的参数 ,可以使用 … ,在变量名后面使用它,它会将这些参数分配给变量
.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
}
- 匹配模式
根据不同的参数,设定不同的行为
@switch:light
.mixin(dark,@color){
color : darken(@color:10%);
}
.mixin(light,@color){
color : lighten(@color:10%);
}
.mixin(@_,@color){ //匹配任意值,但要注意@color必须写
display:block;
}
.a{
.mixin(@switch,#333);
}
注:也可以基于参数个人来匹配
- 作为函数使用的混合
在类似函数的mixin中,变量会充当它的返回值
.mixin() {
@width: 100%;
@height: 200px;
}
.caller {
.mixin(); //先运行
width: @width; //调用返回值
height: @height;
}
//结果:
.caller{
width:100%;
height:200%;
}
带参数的函数混合
.average(@x, @y) {
@average: ((@x + @y) / 2);
}
div {
.average(16px, 50px); // "call" the mixin
padding: @average; // use its "return" value
}
定义在mixin中的mixin同样可以作为返回值
.unlock(@value) { // 外层的 mixin
.doSomething() { // 被嵌套的 mixin
declaration: @value;
}
}
#namespace {
.unlock(5); // unlock doSomething mixin
.doSomething(); //嵌套混入被复制到这里,并可用
}
#namespace {
declaration: 5;
}
在mixin中定义包装的CSS代码块
// 声明 detached 规则集合
@detached-ruleset: { background: red; };
// 使用 detached 规则集合
.top {
@detached-ruleset(); //()这个括号是必须写的
}
//结果为:
.top {
background: red;
}
导入规则
从其他样式表中导入样式。
在标准的CSS中,@import必须在所有其他类型的规则之前。但是Less.js不在乎你把@import语句放在什么位置。
File extensions (文件扩展名)
如果文件有一个.css扩展名,则将它作为CSS对象,其他的则作为Less文件导入进来
Import (导入选项)
语法:@import (keyword) “filename”;
reference:使用Less文件但不输出
inline:在输出中包含源文件但不加工它
less:将文件作为Less文件对象,无论是什么文件扩展名
css:将文件作为CSS文件对象,无论是什么文件扩展名
once:只包含文件一次(默认行为)
multiple:包含文件多次
Mixin Guards (带条件的mixins)
.mixin (@a) when (lightness(@a) >= 50%) {
background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
background-color: white;
}
.mixin (@a) {
color: @a;
}
.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }
//输出
.class1 {
background-color: black;
color: #ddd;
}
.class2 {
background-color: white;
color: #555;
}
- Guard中的比较运算符 (>,>=,=, =<,<) ,此外,关键字true,是让两个mixins等价的唯一真值
.truth (@a) when (@a) { ... }
.truth (@a) when (@a = true) { ... }//除了关键字true,其他任何值都是假值:
注意,你也可以比较其他每个参数或者不使用参数
@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 }
- Guard逻辑运算符
您可以在guards之间使用逻辑运算符。语法是基于CSS媒体查询。
使用and关键字来组合guards:
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
你可以通过用逗号 , 分隔guards来模仿 or 运算符。如果任何 guards 为 true,那么它认为是匹配的:
.mixin (@a) when (@a > 10), (@a < -10) { ... }
使用 not 关键字来否定条件:
.mixin (@b) when not (@b > 0) { ... }
- 类型检查函数
基本的类型检查函数
- iscolor
- isnumber
- isstring
- iskeyword
- isurl
你想检查一个值除了数字是否是一个特定的单位,你可以使用下列方法之一 - ispixel
- ispercentage
- isem
- isunit
- 你还可以通过与&特性结合实现’if’类型的语句,从而允许组合多个约束。
& when (@my-option = true) {
button {
color: white;
}
a {
color: blue;
}
}
Loops (循环)
使用递归循环最常见的情况就是生成栅格系统的CSS:
.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%;
}
Merge (合并)
从多个属性中将值集合到一个单一属性之下的逗号或空格分割属性列表中。对于诸如background和transform之类的属性来说,merge非常有用。
.mixin() {
box-shadow+: inset 0 0 10px #555;
}
.myclass {
.mixin();
box-shadow+: 0 0 20px black;
}
//输出
.myclass {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}
.mixin() {
transform+_: scale(2);
}
.myclass {
.mixin();
transform+_: rotate(15deg);
}
//输出
.myclass {
transform: scale(2) rotate(15deg);
}
为避免任何非有意的添加,merge需要在每个待加入的声明中显示的设置一个+或者+_标记
Parent Selectors (父级选择器)
& 运算符表示一个 嵌套规则 的父选择器,它在应用修改类或者应用伪类给现有选择器时最常用:
a {
color: blue;
&:hover {
color: green;
}
}
//输出
a {
color: blue;
}
a:hover {
color: green;
}
.link {
& + & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
//输出
.link + .link {
color: red;
}
.link .link {
color: green;
}
.link.link {
color: blue;
}
.link, .linkish {
color: cyan;
}