less是一种动态样式语言;为提高css应用的灵活性和效率,less将css赋予了动态语言的特性,如变量、继承、运算、函数。less既可以在客户端上运行,也可以借助Node.js在服务端运行。
css作为一门标记性语言,初学者第一印象简单易懂,毫无逻辑。在新语法更新时,每当新属性提出,浏览器的兼容又会马上称为绊脚石
以@开头定义变量
,并且使用时知己诶键入@名称
,在平时工作中,我们就可以把常用的变量,封装到一个文件中,这样利于代码组织维护。
less文件:
@color: white;
@bg: red;
@width: 200px;
@height: 200px;
#wrap {
color: @color;
background-color: @bg;
width: @width;
height: @height;
}
生成的css文件:
#wrap {
color: white;
background-color: red;
width: 200px;
height: 200px;
}
<link rel="stylesheet" href="./index1.css">
<div id="wrap">
less的变量使用
</div>
让选择器变成动态的,变量名必须用{ }包裹起来
less文件:
//选择器变量
@mySelector:#wrap;
@wrap:wrap;
@border:1px solid black;
@{mySelector}{
color: #ccc;
width: 50%;
border: @border;
}
.@{wrap}{
color: red;
width: 50%;
border: @border;
}
#@{wrap}{
color: blue;
}
生成的css文件:
#wrap {
color: #ccc;
width: 50%;
border: 1px solid black;
}
.wrap {
color: red;
width: 50%;
border: 1px solid black;
}
#wrap {
color: blue;
}
<div id="wrap">
less的变量使用
</div>
<div class="wrap">
less的变量使用
</div>
可以减少代码书写量,属性变量名必须使用{ }包起来
//属性变量
@boderStyle:border-style;
@Solid:solid;
@mySelector:#wrap;
@{mySelector}{
color: #ccc;
width: 50%;
//属性变量名,必须使用{}包起来
@{boderStyle}:@Solid;
}
生成的css文件:
#wrap {
color: #ccc;
width: 50%;
border-style: solid;
}
<div id="wrap">
less的变量使用
</div>
项目结构改变时,修改其变量即可。
@boderStyle: border-style;
@Solid: solid;
@mySelector: #wrap;
//url变量
@images: "../../img";
@{mySelector} {
background-image: url("@{images}/1.jpg");
//属性变量名,必须使用{}包起来
@{boderStyle}: @Solid;
height: 100px;
}
生成的css文件:
#wrap {
background-image: url("../../img/1.jpg");
border-style: solid;
height: 100px;
}
有点类似于下面的混合方法:
@boderStyle: border-style;
@Solid: solid;
@mySelector: #wrap;
//声明变量
@background: {
background-color: red
}
@rules: {
width: 200px;
height: 200px;
}
@{mySelector} {
@background();
@rules();
//属性变量名,必须使用{}包起来
@{boderStyle}: @Solid;
}
生成的css文件:
#wrap {
background-color: red;
width: 200px;
height: 200px;
border-style: solid;
}
注意添加空格
避免变量产生找不到的报错@mySelector: #wrap;
//变量运算
@width: 300px;
@color: #222;
@{mySelector} {
width: @width - 20;
height: @width - 200;
background-color: @color + #333;
//属性变量名,必须使用{}包起来
border: 1px solid red;
}
#wrap {
width: 280px;
height: 100px;
background-color: #555555;
border: 1px solid red;
}
一句话理解:就近原则。
@mySelector: #wrap;
//变量作用域
@var: @a;
@a: 100%;
@{mySelector} {
width: @var;
@a: 20%;
border: 1px solid blue;
}
生成的css文件:
#wrap {
width: 20%;
border: 1px solid blue;
}
@mySelector: #wrap;
//用变量去定义变量
@fond: @var;
@var: "fond";
@{mySelector}::after{
content: @fond;
border: 1px solid blue;
}
生成的css文件:
#wrap::after {
content: "fond";
border: 1px solid blue;
}
& :代表的是上一次选择器的名字
.center {
width: 200px;
height: 200px;
background-color: red;
& #list {
width: 50px;
height: 50px;
background-color: green;
li {
width: 20px;
height: 20px;
background-color: blue;
}
}
& a {
color: black;
}
}
生成的css文件:
.center {
width: 200px;
height: 200px;
background-color: red;
}
.center #list {
width: 50px;
height: 50px;
background-color: green;
}
.center #list li {
width: 20px;
height: 20px;
background-color: blue;
}
.center a {
color: black;
}
<div class="center">
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<a href="https://www.baidu.com">点击跳转百度</a>
</div>
唯一的缺点就是每个元素都会编译出自己的@media声明,并不会合并;
//媒体查询
#main {
@media screen {
@media (max-width: 768px) {
width: 100px;
}
}
@media tv {
width: 2000px;
}
}
@media screen and (max-width: 768px) {
#main {
width: 100px;
}
}
@media tv {
#main {
width: 2000px;
}
}
方法犹如声明的集合,使用时直接键入名称即可。
//.card与.card()是等效的,为了避免代码混淆,可以写成.card()
.card(){
width: 100px;
height: 100px;
background: yellow;
margin: 10px;
box-shadow: 0 1px 2px rgba(150,150,150,58);
-webkit-box-shadow:0 1px 2px rgba(150,150,150,58);
}
#wrap{
.card();
}
#wrap {
width: 100px;
height: 100px;
background: yellow;
margin: 10px;
box-shadow: 0 1px 2px #969696;
-webkit-box-shadow: 0 1px 2px #969696;
}
传的参数中必须带单位
.border(@a:1px,@b:50px,@c:30px,@color:red) {
border: solid 1px @color;
//@argument指代传进来的全部参数
box-shadow: @arguments;
}
#wrap {
.border();
}
css:
#wrap {
border: solid 1px red;
box-shadow: 1px 50px 30px red;
}
//方法匹配模式
.triangle(top,@width:20px,@color:red) {
border-color: @color transparent transparent transparent;
}
.triangle(right,@width:20px,@color:green) {
border-color: transparent @color transparent transparent;
}
.triangle(bottom,@width:20px,@color:orange) {
border-color: transparent transparent @color transparent;
}
.triangle(left,@width:20px,@color:blue) {
border-color: transparent transparent transparent @color;
}
.triangle(@_,@width:20px,@color:#fff) {
border-style: solid;
}
#wrap {
width: 100px;
height: 100px;
.triangle(right, 50px, #222222)
}
css:
#wrap {
width: 100px;
height: 100px;
border-color: transparent #222222 transparent transparent;
border-style: solid;
}
//方法的命名空间
#card() {
background: red;
.d(@w:300px) {
width: @w;
#a(@h:300px) {
height: @h;
}
}
}
#wrap {
//父级方法就不需要加()了
#card > .d > #a(100px);
border: 1px solid green;
}
#main {
#card .d();
border: 1px solid red;
}
#con {
//不得单独使用命名空间的方法
#card();
//.d()如果前面没有引入命名空间#card,就会报错
.d(200px);
}
css:
#wrap {
height: 100px;
border: 1px solid green;
}
#main {
width: 300px;
border: 1px solid red;
}
#con {
background: red;
width: 200px;
}
less没有if else,可是它有when;
//方法的条件筛选
#card {
//when &&
.border(@width,@color,@style) when(@width>100px) and (@color=#999){
border: @style @color @width;
}
//when not !
.background(@color) when not (@color>=#222) {
background: @color;
}
// , 逗号分隔符方法 ||
.font(@size:20px) when (@size<50px), (@size>100px) {
font-size: @size;
}
}
#wrap {
#card>.border(10px, #999, solid);
#card>.background(#444);
#card>.font(40px);
}
css:
#wrap {
background: #444;
font-size: 40px;
}
如果你希望你的方法接收数量不定的参数,可以使用…,犹如ES6的扩展运算符。
//数量不定的参数
.boxShadow(...) {
box-shadow: @arguments;
}
.textShadow(@a,...) {
text-shadow: @arguments;
}
#wrap {
box-shadow: 1px 4px 10px red;
text-shadow: 1px 4px 20px #0400ff;
}
css:
#wrap {
box-shadow: 1px 4px 10px red;
text-shadow: 1px 4px 20px #0400ff;
}
使用方法:在方法名后加上关键字即可
.border(){
border: 1px solid red;
}
#wrap{
.border() !important;
}
css:
#wrap {
border: 1px solid red !important;
}
less并没有提供for循环的功能,但是可以使用递归实现。
//循环方法 递归的循环方法
.generate-colums(4);
.generate-colums(@n,@i:1) when (@i<=@n) {
.column-@{i} {
width: (@i*100%/@n);
}
.generate-colums(@n, (@i+1))
}
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
//属性拼接方法
.boxShadow() {
box-shadow+: inset 0 0 10px #555;
}
#wrap {
.boxShadow();
box-shadow+: 0 0 20px black;
}
.animation() {
transform+: scale(2);
}
#wrap {
.animation();
transform+_: rotate(15deg);
}
css
#wrap {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}
#wrap {
transform: scale(2) rotate(15deg);
}
extend是less的一个伪类,它可继承所有匹配声明中的全部样式。
.animation {
transition: all .3s ease-out;
.hide {
transform: scale(0);
}
}
#wrap {
&:extend(.animation);
}
#con {
&:extend(.animation .hide);
}
.animation,
#wrap {
transition: all 0.3s ease-out;
}
.animation .hide,
#con {
transform: scale(0);
}
使用选中器匹配到的全部声明
#main {
width: 200px;
}
#main {
&:after {
content: "less is good";
}
}
#wrap:extend(#main all) {
border: 1px solid red;
}
#main,
#wrap {
width: 200px;
}
#main:after,
#wrap:after {
content: "less is good";
}
#wrap {
border: 1px solid red;
}
extend与方法最大的差别,就是extend是同一个选择器共用同一个声明,而方法是使用自己的声明,这增加了代码的重复性;
与上面的代码进行比对:
#Method() {
width: 200px;
&:after {
content: "less is good";
}
}
#wrap {
#Method();
border: 1px solid red;
}
#wrap {
width: 200px;
border: 1px solid red;
}
#wrap:after {
content: "less is good";
}
@import “less文件名”;
使用引入的less文件,但是不会编译;
@import (reference) “less文件名”;
@import语句的默认行为,这表明相同的文件之后被导入一次,而随后导入的文件的重复代码都不会被解析
@import (once) “less文件名”;
使用 @import (multiple)允许导入多个同名文件;
@import (multiple) “less文件名”;
.mixin(@a) when (lightness(@a)>=50%) {
background: black;
}
.mixin(@a) when (lightness(@a)<50) {
background: orange;
}
.mixin(@a) {
color: @a;
}
#wrap {
background: orange;
color: #555;
}
检测值的类型
.mixin(@a:#fff;@b:16px) when (isNumber(@b)) {
color: @a;
font-size: @b;
}
.mixin(@a,@b:balck) when (isColor(@b)) {
font-size: @a;
color: @b;
}
#wrap{
.mixin(#666,30px)
}
#wrap {
color: #666;
font-size: 30px;
}
检测一个值除了数字是否是一个特定的单位
body{
color: color("#f60");
background-color: color("red");
}
body {
color: #f60;
background-color: #ff0000;
}