初识 Less Less 是什么 Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。 Less 可以运行在 Node 或浏览器端。最基础的例子如下所示:
1 2 3 4 5 6 7 8 9 @base: #fff; .wh (@width , @height ) { width : @width; height : @height; } .box { color : @base; .wh('30px', '30px') }
编译输出后的结果:
1 2 3 4 5 .box { color : #fff ; width : '30px' ; height : '30px' ; }
浏览器中使用 Less 我们如何在网页中使用 Less 呢?有两种形式,第一种是通过 npm 下载 Less 包,通过 webpack 打包编译后可以编译成最终的 CSS。第二种是直接通过 Less 脚本在 HTML 页面中使用。 本章为了方便学习 Less 的语法知识,选择第二种形式。首先我们创建一个 Less 文件夹,在文件夹内新建一个 index.html 文件,和style.less文件:
随后我们需要去找 Less 的静态资源,在此推荐大家一个好用的静态资源网站,里面有很多前端相关的静态资源— BootCDN 。 最后我们练手的 index.html 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Document</title > </head > <body > <div class ="box" > <span > 我是less</span > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
styles.less 代码如下:
1 2 3 4 5 .box { span { color : red; } }
浏览器中的效果如下:
Less 的使用 Less 中的注释
以 //
开头的注释,注释单行,且不会被编译到 CSS 文件中。
以 /**/
包裹的注释,注释多行,同样也不会被编译到 CSS 文件中。
Less 中的变量 Less 中使用 @
符号申明变量,比如 @color: red
。比方说我现在写一个电商项目,我需要设置项目中主色、辅助色等,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Document</title > </head > <body > <div class ="box" > <p class ="one" > 我是less</p > <p class ="two" > 我是less</p > <p class ="three" > 我是less</p > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @primary: red;@deepColor: green;@lightColor: blue;.box { .one { color : @primary ; } .two { color : @deepColor ; } .three { color : @lightColor ; } }
有一点要注意的是,如果在后面声明了同名变量,变量值会被后面的覆盖,比如上述代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @primary: red;@deepColor: green;@lightColor: blue;@primary: pink.box { .one { color : @primary ; } .two { color : @deepColor ; } .three { color : @lightColor ; } }
那么第一个p标签.one下的“我是Jungle”就会为pink,即:同权重选择器前后覆盖。
程序员要培养自己的举一反三能力,颜色可以写成变量,文字的大小同样也可以,并且 less 文件能通过 @import
关键词引入其他的 less 文件
Less 中的嵌套 市面上所有 CSS 的预编译器的嵌套规则大同小异,基本嵌套如下:
1 2 3 4 5 6 .a { color : #fff ; .b { width : 20px ; } }
编译后的代码如下所示:
1 2 3 4 5 6 .a { color : #fff ; } .a .b { width : 20px ; }
同级场景 &
的使用如下所示:
1 2 3 4 5 6 .a { color : blue; & :hover { color : red; } }
上述代码 &
表示当前节点的 CSS 样式,一般用于处理 CSS 样式的状态 hover、focus、active、link、visited等。
Less 中的混合(Mixin) Less 的混合有三种情况:
不带参数;
带参数,没有默认值;
带参数,且有设置默认值;
调用的时候也存在区别:
不带参数:调用时可以不加括号,直接使用;
带参数:调用时要加括号,括号里必须要传值,不然编译会报错;
带参数且有默认值:调用时要加括号,参数可传可不穿;
下面就用上面的 Demo 页面进行实验,首先是第一种情况,不带参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // index.html <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <p class ="one" > 我是less</p > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 .center { text-align : center; } .red { color : red; } .box { .one { .center ; .red ; } }
下面是带参数,且没有默认值的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 .center { text-align : center; } .color (@c ) { color : @c ; } .box { .one { .center ; .color (green); } }
最后是带默认值的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 .center { text-align : center; } .color (@c : red) { color : @c ; } .box { .one { .center ; .color ; } }
在开发页面时,时常会有需要画三角形的情况,上下左右四个方位的三角形,若是一直复制重复的代码去修改,显得不是那么优雅,这时候我们可以用到匹配模式。 匹配模式下无论同名的哪一个混合被匹配到,都会先执行通用匹配模式的代码, @_
表示通用的匹配模式,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <p > </p > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 .triangle (@_ , @width , @color ) { width : 0 ; height : 0 ; border-style : solid; } .triangle (Bottom, @width , @color ) { border-width : @width ; border-color : @color transparent transparent transparent; } .triangle (Left, @width , @color ) { border-width : @width ; border-color : transparent @color transparent transparent; } .triangle (Top, @width , @color ) { border-width : @width ; border-color : transparent transparent @color transparent; } .triangle (Right, @width , @color ) { border-width : @width ; border-color : transparent transparent transparent @color ; } .box { p { .triangle (Left, 100px , red); } }
上述 Less 代码设置了基础的 .triangle
样式,再分别设置上下左右四个方位的匹配模式,并且可以通过 @width
参数来控制三角形大小,浏览器的展示如下所示:
你可以把配置写进共用的样式库中,在需要用到的地方通过 @import
关键字引入。
arguments 变量:使用 @arguments
表示 mixin 的所有参数,代码示例如下:
1 2 3 4 5 6 7 .border (@width , @mode , @color ) { border : @arguments ; } .one { .border (1px , solid, red) }
Less 中的运算 算数运算符 +、-、*、/ 可以对任何数字、颜色或者变量进行运算,在 Less 中在加减之前会进行单位的换算。计算的结果以最左侧才作数的单位类型为准。如果单位无效或者失去意义,则单位会被忽略。
1 2 width : 20px + 20 ; color : #444 * 2 ;
calc() 特例
为了与 CSS 保持兼容, calc()
方法并不会对数学表达式进行计算,但是在嵌套函数中会计算变量的数学公式的值。代码如下所示:
1 2 @a: 100vh /2 height : calc(50% + (@a - 40px ));
Less 中的转译 转译,简单的理解就是我们原先是什么样的,最终输出的还是什么样。关键字是 ~""
,示例代码如下:
1 2 3 p { color : ~"green" ; }
在 Less 3.5+ 版本中,许多以前需要“引号转义”的情况就不再需要了。
Less 中的作用域 Less 中的作用域和 CSS 的作用域非常相似,首先 Less 会查询当前作用域内的变量和混合(mixins),如果找不到的话会继续向上一级查询,直到找到为止。示例代码如下:
1 2 3 4 5 6 7 @var: blur;body { @var: red; .one { color : @var ; } }
Less 中的导入 现代前端开发,万物皆是模块。Less 也不例外,我们一个 Less 文件就可以当作一个模块来处理,一个 Less 文件中可以引入另外一个 Less 文件,并且可以使用里面的变量信息,我们来看实例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <p > 我是P</p > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 @import './styles1.less' ;@color1: red;.box { p { color : @color2 ; } }
声明变量的时候,颜色主题可以单独创建一个 Less 文件。字体大小,文字粗细,阴影的大小,透明度等等也可以单独抽离一个 Less 文件,通过引入的方式全部引入到 index.less 中,在组件中使用的时候,可以只引入 index.less 文件,便可使用在 index.less 中引入的 Less 文件的变量。
Less 使用实例 文字超出省略 这是前端开发中出现频率比较高的情况,我们来提取混合(Mixin),实例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <div class ="text" > 我是less我是less我是less我是less我是less我是less我是less</div > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .ellipsisSingle { -webkit-box-orient: vertical; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; } .box { .text { .ellipsisSingle ; background : darkgoldenrod; width : 200px ; height : 20px ; } }
若是需要多行省略的情况呢?下面就用到了带参数的混合(Mixin):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <div class ="text" > 我是less我是less我是less我是less我是less我是less我是less</div > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
styles.less:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .ellipsisMultiple (@num : 1 ) { display : -webkit-box; -webkit-box-orient: vertical; overflow : hidden; text-overflow : ellipsis; -webkit-line-clamp: @num; } .box { .text { .ellipsisMultiple (2 ); background : darkgoldenrod; width : 200px ; } }
文字垂直居中 很多时候你在写 CSS 样式的时候,会连续写两个连在一起的属性,比如 height: 20px; line-height: 20px
,目的是为了让标签内的文字垂直居中,写多了就会觉得代码不是那么干净。又到了 Less 出手的时候了,把它封装起来,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 .line-text-h (@h : 0 ) { height : @h ; line-height : @h ; } .box { .text { .line-text-h (100px ); background : darkgoldenrod; width : 200px ; } }
定位上下左右居中 项目开发中有些场景比如设置空页面的图标上下左右居中,这时我们可以封装一个 Less 混合(Mixin):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .center { position : absolute; top : 50% ; left : 50% ; transform : translate(-50% , -50% ); } .box { .text { .center ; background : darkgoldenrod; width : 200px ; height : 200px ; } }
三角形绘制 三角形的绘制在开发中也是很常见,特别是上下左右四个方向的三角形,每次编写的时候代码都非常冗余,会有不少重复代码,在此我们可以使用 Less 传入参数的形式,控制三角形的样式和方向:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <link rel ="stylesheet/less" type ="text/css" href ="./styles.less" /> <title > Less</title > </head > <body > <div class ="box" > <p > </p > </div > <script src ="https://cdn.bootcss.com/less.js/3.11.1/less.min.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 .triangle (@_ , @width , @color ) { width : 0 ; height : 0 ; border-style : solid; } .triangle (Bottom, @width , @color ) { border-width : @width ; border-color : @color transparent transparent transparent; } .triangle (Left, @width , @color ) { border-width : @width ; border-color : transparent @color transparent transparent; } .triangle (Top, @width , @color ) { border-width : @width ; border-color : transparent transparent @color transparent; } .triangle (Right, @width , @color ) { border-width : @width ; border-color : transparent transparent transparent @color ; } .box { p { .triangle (Top, 100px , blue); } }
总结 市面上 CSS 预编译器大同小异,语法大抵相同,不同的可能是一些变量符号,学好 Less,切换 Sass 或是 Stylus 都是比较轻松的。
规划好 Less 文件,在实际开发项目中能事半功倍,可以把更多的精力放在业务逻辑上,而不会因为改一个样式问题导致“牵一发动全身”。