Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。
一、使用方法
Node环境
安装LESS:
$ npm install -g less
使用以下命令将 style.less 文件编译为 style.css :
$ lessc style.less style.css
浏览器环境
1、在页面中 引入 Less.js 可在官网下载或使用CDN
需要注意的是,link 标签一定要在 Less.js 之前引入,并且 link 标签的 rel 属性要设置为stylesheet/less。
变量(Variables)
几种变量类型:选择器变量、属性变量、属性值变量、Url变量
css的构成:
h1 { font-size : 12px }
选择器 属性 属性值
定义变量:@变量名:变量值
@变量名:变量值
@mySelector: #wrap; //选择器变量
@borderStyle: border-style; //属性变量
@color:#333; //属性值变量
@images: "../img"; //Url变量
调用变量:除了属性值变量是@变量名,其他都是@{变量名}
@{mySelector}{ //选择器变量@{变量名}
color: #999;width: 50%
}
#wrap{
@{borderStyle}:solid; //属性变量@{变量名}
}
#wrap{
Background:@color; //属性值变量 @变量名
}
#wrap{
background: url("@{images}/bg.png"); //Url变量 @{变量名}
}
声明变量与混合(Mixin)的区别:
声明变量:与普通css样式的区别是前缀使用@,名字与值用:相连。
定义:@变量名: { 属性: 属性值 };
调用:@变量名();
混合(Mixin):与普通css样式无差别,当带有()时,将不会在样式中输出
声明:.或#变量名(){ 属性: 属性值 };
调用:.或#变量名();
声明变量:@变量名: { 属性: 属性值 };
@background: {background:red}; //定义变量
#main{
@background(); //调用变量
}
#main {
background: red;
}
混合(Mixin):. 或 # 变量名(){ 属性: 属性值 };
.background(){background:red}; //定义变量
#main{
.background(); //调用变量
}
变量运算
加减法时,以第一个数据的单位为基准。
乘除法时,注意单位一定要统一。
@width:300px;
@color:#222;
#wrap{
width:@width-20;
height:@width-20*5;
margin:(@width-20)*5;
color:@color*2;
background-color:@color + #111;
}
/* 生成的 CSS */
#wrap{
width:280px;
height:200px;
margin:1400px;
color:#444;
background-color:#333;
}
变量的作用域
就近原则。不是指代码的位置,而是指代码的层级结构。
- 同一级后面的生效,类似于提升。
- 不同级的变量,定义时的位置最近的生效。
@var: @a;
@a: 100%;
#wrap {
width: @var;
@a: 9%; //同级后面的生效
}
/* 生成的 CSS */
#wrap {
width: 9%;
}
用变量去定义变量
@fnord: "I am fnord.";
@var: "fnord";
#wrap::after{
content: @@var; //将@var替换为其值 content:@fnord;
}
/* 生成的 CSS */
#wrap::after{
content: "I am fnord.";
}
嵌套
将一个类的属性用于另一个类。 它模仿了 HTML 的结构,使代码看起来更加清晰和简洁。
#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}
这时,我们用嵌套的规则可以将其写成:
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
- 在嵌套中,可以用'&'表示父类。
#header{
&:after{
content:"Less is more!";
}
.title{
font-weight:bold;
}
&_content{ //理解方式:直接把 & 替换成 #header
margin:20px;
}
}
/* 生成的 CSS */
#header::after{
content:"Less is more!";
}
#header .title{ //嵌套了
font-weight:bold;
}
#header_content{ //没有嵌套!
margin:20px;
}
- 嵌套覆盖原有样式
div{
width:200px;
height:200px;
background:red;
.show{
display: none;
}
}
.show{
display: block; //在div使用show 会被 div .show 覆盖}
- 其他形式
.select {
& + & {color: #A9F5F2;}
& & { color: #D0FA58;}
&& { color: #81BEF7;}
&, &_class1 {color: #A4A4A4;}
}
/* 生成的 CSS */
.select + .select {color: #A9F5F2;}
.select .select {color: #D0FA58;}
.select.select {color: #81BEF7;}
.select,.select_class1 {color: #A4A4A4;}
继承(Extend)
- 放置Extend 的选择器被合并进Extend指向的选择器中。
.a{
color: red;
}
.text {
background-color: #0d94f3;
&:extend(.a);
font-size: 12px;
}
/* 生成后的 CSS */
.a,.text {
color: red;
}
.text {
background-color: #0d94f3;
font-size: 12px;
}
- 嵌套继承选择器
.parentClass{
span{
color:red
}
}
.subClassOne{
&:extend(.parentClass span);
}
/* 生成后的 CSS */
.parentClass span,
.subClassOne {
color: red;
}
- all 替换全部样式
#main{
width: 200px;
}
#main {
&:after {
content:"Less is good!";
}
}
#wrap:extend(#main all) {}
/* 生成后的 CSS */
#main,#wrap {
width: 200px;
}
#main:after,#wrap:after {
content: "Less is good!";
}
混合(Mixin)
1、创建一个混合
声明:.或#变量名() { 属性: 属性值 }; //声明时如果带有(),此样式将不会在样式中输出。
调用:.或#变量名();
.card() { //生成的样式中没有次类
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
#wrap{
.card();
}
/* 生成的 CSS */
#wrap{
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
要点:“.”与“#”都可以作为方法前缀,写法与普通样式的没有区别。但方法后加上小括号“()”后,将不会在样式中输出。
2、可以把选择器写在混合集中
.my-hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.my-hover-mixin();
}
// 将会输出:
button:hover {
border: 1px solid red;
}
3、可以在混合中,使用嵌套
#outer {
.inner {
color: red;
}
}
.c {
#outer > .inner;
}
// 输出:
.c {
color: red;
}
4、()中可以接受传递参数,参数为 @+变量名 的形式。
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius(4px);
}
/* 生成后的 CSS */
#header {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
4.1 可以带多个参数,参数间用 ,相隔。
.mixin(@color: black, @margin: 10px, @padding: 20px) {
color: @color;
margin: @margin;
padding: @padding;
}
.class1 {
.mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
.mixin(#efca44; @padding: 40px);
}
/* 生成的 CSS */
.class1 {
color: #33acfe;
margin: 20px;
padding: 20px;
}
.class2 {
color: #efca44;
margin: 10px;
padding: 40px;
}
4.2 为参数设定默认值方法
如果没有传参数,那么将使用参数默认值。 @arguments 指代的是全部参数。 传的参数中必须带着单位。
.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; //未传参数,全部使用参数默认值
}
/* 生成的 CSS */
#main{ //传递了box-shadow的参数,其余参数默认值
border:solid 1px red;
box-shadow:0px,5px,30px,red;
}
#wrap{ //设置了一个值0px,其它全部使用参数默认值
border:solid 1px #000;
box-shadow: 0px 50px 30px #000;
}
#content{ //未传参数,全部使用参数默认值
border:solid 1px #000;
box-shadow: 10px 50px 30px #000;
}
4.3 数量不定的参数
如果你希望你的方法接受数量不定的参数,你可以使用... 加@arguments
.boxShadow(...){
box-shadow: @arguments;
}
.textShadow(@a,...){
text-shadow: @arguments;
}
#main{
.boxShadow(1px,4px,30px,red);
.textShadow(1px,4px,30px,red);
}
/* 生成后的 CSS */
#main{
box-shadow: 1px 4px 30px red;
text-shadow: 1px 4px 30px red;
}
5、方法名的匹配
同一个类的多个方法,由第一个不带@的参数代表方法名。匹配不同的样式,@_可存放公共的样式。
.triangle(top,@width:20px,@color:#000){
border-color:transparent transparent @color transparent ;
}
.triangle(right,@width:20px,@color:#000){
border-color:transparent @color transparent transparent ;
}
.triangle(bottom,@width:20px,@color:#000){
border-color:@color transparent transparent transparent ;
}
.triangle(left,@width:20px,@color:#000){
border-color:transparent transparent transparent @color;
}
.triangle(@_,@width:20px,@color:#000){
border-style: solid;
border-width: @width;
}
#main{
.triangle(left, 50px, #999) //匹配 left 方法中的样式。
}
/* 生成的 CSS */
#main{
border-color:transparent transparent transparent #999;
border-style: solid;
border-width: 50px;
}
如果匹配程度相同,将全部选择,并存在着样式覆盖。 @_ 这个就可以用来做相同的公共的样式部分。
6、作为函数使用
.mixin() {
@width: 100%;
@height: 200px;
}
.caller {
.mixin();
width: @width;
height: @height;
}
将会输出:
.caller {
width: 100%;
height: 200px;
}
7、定义的变量来充当它的返回值(return value):
.average(@x, @y) {
@average: ((@x + @y) / 2);
}
div {
.average(16px, 50px); // 参数传入mixin
padding: @average; // 读取mixin中的变量
}
结果
div {
padding: 33px;
}
8、方法的命名空间
1、在 CSS 中>
选择的是子元素
2、在引入命令空间时,如使用 >
,父元素不能加括号 ()。
3、不得单独使用命名空间中的方法 必须先引入命名空间,才能使用其中方法。
4、子方法 可以使用上一层传进来的方法
#card(){
background: #723232;
d(@w:300px){
width: @w;
#a(@h:300px){
height: @h;
width: @w; //可以使用上一层传进来的方法
}
}
}
#wrap{
#card > .d > #a(100px); // 父元素不能加 括号,d 为传入参数使用默认值,width:300px,#a 参数height为100px
}
#main{
#card .d(); //未传参数将使用默认值,width:300px
}
#con{
.d() // 报错,不得单独使用命名空间的方法,前面没有引入命名空间 #card
#card; // 等价于 #card();
.d(20px); //不报错,上面已经引入了 #card,可以正常执行。,参数输入width为20px
}
/* 生成的 CSS */
#wrap{
height:100px;
width:300px;
}
#main{
width:300px;
}
#con{
width:20px;
}