共计 6917 个字符,预计需要花费 18 分钟才能阅读完成。
less
前言
Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充。
安装
客户端使用
// 引入 .less 文件,rel 属性值为:“stylesheet/less”
<link rel=”stylesheet/less” type=”text/css” href=”index.less”>
// 在引入 .less 文件之后,引入 less.js 文件,官网下载或者使用 CDN;
<script src=”https://cdn.bootcss.com/less.js/3.9.0/less.js” type=”text/javascript”></script>
监控模式 是客户端的一个功能,当改变样式的时候,客户端将自动刷新。
使用:只需在 URL 后面加上 ’#!watch’,然后刷新页面就可以了。
服务端使用
// 安装(通过 npm)
> npm install less (npm install less@latest // 安装最新稳定版本)
// 使用
// 在 node 中调用编译器
var less = require(“less”);
less.render(“.class{color:#184e1}”, function(e, css){
console.log(css);
})
// 输出
.class {
color:#184e1;
}
// 在命令行下使用
> lessc index.less > index.css
// (如何要将编译后的 CSS 压缩掉,那么加一个 -x 参数就可以了.)
详情请点击 less 官网。
语法
1. 变量
Less 变量:以 @ 开头 定义变量
允许我们定义一系列通用样式,在需要的地方调用。
后期调整全局样式 | 主题的时候,只需修改几行代码就可以,方便快捷,易于维护。
// less
@boxW:1220px;
.container{
width : @boxW;
}
// 生成 css
.container{
width : 1220px;
}
属性变量
// less
@borderStyle: border-style;
@Soild:solid;
#wrap{
@{borderStyle}: @Soild;// 变量名 必须使用大括号包裹
}
// 生成的 CSS
#wrap{
border-style:solid;
}
使用变量名定义变量
// less
@say:” Hello Less ~”;
@var:”say”;
.el{
content: @@var;
}
// 生成 css
.el {
content: ” Hello Less ~”;
}
[注]:当变量作为选择器、属性、URL 变量时,变量名 必须使用大括号包裹
2. 混合
Less 混合:可以将一个定义好的 style1 引入到另一个 style 中,使后者继承前者的所有属性. 与 # 皆可作为 方法前缀。
1). 无参调用
定义一些通用的属性集为一个 class,然后在另一个 class 中去调用这些属性
// less
.br2 {border-radius: 2px;} // 这样定义,.br2 会暴露到 css 中
button{
width:100px;
height:50px;
.br2; // 等价于 .br2();
}
// 生成 css
button {
width: 100px;
height: 50px;
border-radius: 2px;
}
2). 带参调用
可以像函数一样定义一个带参数的属性集合:
// less
.mt(@mt) {margin-top: @mt;}
.mb(@mb) {margin-bottom: @mb;}
div{
.mt(10px);
.mb(20px)
}
// 生成 css
div {
margin-top: 10px;
margin-bottom: 20px;
}
给参数设置默认值
// less
.mt(@mt:10px) {margin-top: @mt;}
.mb() { margin-bottom: 20px;} // 这样定义,.mb 不会暴露到 css 中
div{
.mt;
.mb;
}
// 生成 css
div {
margin-top: 10px;
margin-bottom: 20px;
}
[注]:在 Less 中定义的不带参属性集合,如果想隐藏这个集合 (即 不让它暴露到 css 中),但可以在其他地方引用,可以这样写:.mb {margin-bottom: 20px;} 要写成 .mb() { margin-bottom: 20px;}
@arguments 变量
@arguments 变量 包含了所有传递进来的参数
// less
.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
box-shadow: @arguments;
}
.el{
.box-shadow(2px, 5px);
}
// 生成 css
.el{
box-shadow: 2px 5px 1px #000;
}
数量不定的参数
如果你希望你的方法接受数量不定的参数,你可以使用 …,犹如 ES6 的扩展运算符。
// less
.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;
}
循环方法 (递归实现)
// less
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
.generate-columns(4);
// 生成 CSS
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
属性拼接
+_ 代表的是 空格;+ 代表的是 逗号。
// less
.boxShadow() {
box-shadow+: inset 0 0 10px #555;
}
.main {
.boxShadow();
box-shadow+: 0 0 20px black;
}
// 生成 CSS
.main {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}
///////////////////////////////
// less
.Animation() {
transform+_: scale(2);
}
.main {
.Animation();
transform+_: rotate(15deg);
}
// 生成 CSS
.main {
transform: scale(2) rotate(15deg);
}
3. 嵌套
Less 嵌套:我们可以在父选择器中嵌套子选择器,实现子继承父。优点:减少了代码量,是结构更加清晰。
// less
.btn-blue {
background-color: #118431;color: #fff;
p{color:#1184e1;}
&:hover {background-color: #39a2ed;}
}
// 生成 css
.btn-blue {
background-color: #118431;
color: #fff;
}
.btn-blue p {
color: #1184e1;
}
.btn-blue:hover {
background-color: #39a2ed;
}
& 符号:串联选择器时使用,代表的上一层选择器的名字。此处例子中:& 直接替换为 .btn-blue。
4. 运算
Less 提供了加,减,乘,除操作,可以做属性值和颜色值的运算
// less
@v2-contWidth: 1220px;
@v2-m: 20px;
@v2-col-1:(@v2-contWidth – @v2-m * 11) / 12;
@v2-col-3:@v2-col-1 * 3 + @v2-m * 2;
.v2-col-1 {width: @v2-col-1;}
.v2-col-3 {width: @v2-col-3;}
// 生成 css
.v2-col-1 {
width: 83.33333333px;
}
.v2-col-3 {
width: 290px;
}
[注]:- 加减法时 以第一个数据的单位为基准 – 乘除法时 注意单位一定要统一
5. 继承
extend 是 Less 的一个伪类。它可继承 所匹配声明中的全部样式。
// less
.par{
color:#1184e1;
.child{color:#333;}
}
.sib{
&:extend(.par);
}
// 生成 css
.par, .sib {
color: #1184e1;
}
.par .child {
color: #333;
}
6.Color 函数
引用官网的例子
// return a color which is 10% *lighter* than @color
// 返回比 @color 轻 10%* 的颜色
lighten(@color, 10%);
// return a color which is 10% *darker* than @color
darken(@color, 10%);
// return a color 10% *more* saturated than @color
// 返回比 @color 饱和 10%* 以上的颜色
saturate(@color, 10%);
// return a color 10% *less* saturated than @color
desaturate(@color, 10%);
// return a color 10% *less* transparent than @color
// 返回比 @color 少 10%* 的颜色 * 透明
fadein(@color, 10%);
// return a color 10% *more* transparent than @color
fadeout(@color, 10%);
// return @color with 50% transparency
// 返回 @color,透明度为 50%
fade(@color, 50%);
// return a color with a 10 degree larger in hue than @color
// 返回颜色比 @color 大 10 度的颜色
spin(@color, 10);
// return a color with a 10 degree smaller hue than @color
spin(@color, -10);
// return a mix of @color1 and @color2
// 返回 @ color1 和 @ color2 的混合
mix(@color1, @color2);
7.Math 函数
引用官网的例子
round(1.67); // returns `2`
ceil(2.4); // returns `3`
floor(2.6); // returns `2`
// 将一个值转化为百分比
percentage(0.5); // returns `50%`
8. 匹配 | 引导
1). 匹配 (根据值和参数匹配)
只有被匹配的混合才会被使用。变量可以匹配任意的传入值,而变量以外的固定值就仅仅匹配与其相等的传入值。
// 语法
.mixin (@s, @color) {。。。}
.class {
.mixin(@switch, #888);
}
// 让.mixin 根据不同的 @switch 值而输出内容
// less
.mixin (dark, @color) {
color: darken(@color, 10%);
}
.mixin (light, @color) {
color: lighten(@color, 10%);
}
.mixin (@_, @color) {// 如果匹配的参数 是变量,则将会匹配,如 `@_`。
display: block;
}
@switch: light;
.class {
.mixin(@switch, #888);
}
// 生成 css
.class {
color: #a2a2a2;
display: block;
}
2). 引导 (根据表达式进行匹配)
when 关键字用以定义一个导引序列,来实现条件判断。导引中可用的全部比较运算有:>、>=、=、=<、<。
= 代表的是等于
// less
.posi (@posi, @bdw) when (@posi = ‘top’) {
border-top-width:@bdw;
}
.posi (@posi, @bdw) when (@posi = ‘bottom’) {
border-bottom-width:@bdw;
}
.line(@posi, @bdw){
.posi(@posi, @bdw);
}
.v2-line_t_s-e5{
.line(‘top’, 1px);
}
.v2-line_b_s-e5{
.line(‘bottom’, 10px);
}
// 生成 css
.v2-line_t_s-e5 {
border-top-width: 1px;
}
.v2-line_b_s-e5 {
border-bottom-width: 10px;
}
导引序列使用逗号‘,’—分割,当且仅当所有条件都符合时,才会被视为匹配成功。
.mixin (@a) when (@a > 10), (@a < -10) {…}
基于值的类型进行匹配,我们就可以使用 is* 函式
.mixin (@a, @b: 0) when (isnumber(@b)) {…}
// 常见的检测函式:
iscolor
isnumber
isstring
iskeyword
isurl
// 判断一个值是纯数字,还是某个单位量
ispixel
ispercentage
isem
在导引序列中可以使用 and 关键字实现与条件;使用 not 关键字实现或条件
.mixin (@a) when (isnumber(@a)) and (@a > 0) {…}
.mixin (@b) when not (@b > 0) {…}
9. 命名空间
为了更好组织 CSS 或者单纯是为了更好的封装,将一些变量或者混合模块打包起来,之后可以重复使用
#bundle {
.button () {
border: 1px solid black;
&:hover {background-color: white}
}
.tab {…}
.citation {…}
}
// #header 的子元素 a 有 .button 的样式,
// 可以这样:#header a 中引入 .button
#header a {
color: orange;
#bundle > .button;
}
–>
// 等价于
#header a {
color: orange;
#bundle;
.button;
}
<–
// 生成 css
#header a {
color: orange;
border: 1px solid black;
}
#header a:hover {
background-color: #ffffff;
}
[注]: 1. 父元素不能加 括号。如:#bundle > .button
2. 不得单独使用命名空间的方法。如:.button // 会报错
10. 作用域
LESS 中的作用域跟其他编程语言非常类似,首先会从本地查找变量或者混合模块,如果没找到的话会去父级作用域中查找,直到找到为止. 一句话理解就是:就近原则
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
#footer {
color: @var; // red
}
11. 字符串插值
变量可以用类似 ruby 和 php 的方式嵌入到字符串中,像 @{name} 这样的结构:
@base-url: “http://assets.fnord.com”;
background-image: url(“@{base-url}/images/bg.png”);
12. 避免编译
有时候我们需要输出一些不正确的 CSS 语法或者使用一些 LESS 不认识的专有语法. 要输出这样的值我们可以在字符串前加上一个 ~
将要避免编译的值用“”包含起来,结构:~’ 值 ‘
.class {
filter: ~”ms:alwaysHasItsOwnSyntax.For.Stuff()”;
}
// 输出为
.class {
filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
}
13. JavaScript 表达式
JavaScript 表达式也可以在.less 文件中使用。
// 可以通过反引号的方式使用
@var: `”hello”.toUpperCase() + ‘!’`;
–> @var: “HELLO!”;
// 可以同时使用字符串插值和避免编译
@str: “hello”;
@var: ~`”@{str}”.toUpperCase() + ‘!’`;
–> @var: HELLO!;
// 可以访问 JavaScript 环境
@height: `document.body.clientHeight`;
// 将一个 JavaScript 字符串解析成 16 进制的颜色值, 你可以使用 color 函数
@color: color(`window.colors.baseColor`);
@darkcolor: darken(@color, 10%);
14. 其他
reference
// 使用 @import (reference) 导入外部文件,但不会添加 把导入的文件 编译到最终输出中,只引用。
@import (reference) “bs.less”;