Less 知识点总结

169 阅读6分钟

前言

Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。

基本概念

变量(Variables)

less使用@符号来标识变量。

例子:

@width: 10px;
@height: @width + 10px;
#header { 
  width: @width;
  height: @height; 
}

编译为:

#header { 
  width: 10px;
  height: 20px; 
}

变量插值

选择器(Selectors)

例子:

@my-selector: banner;
@images: "../img";
.@{my-selector} {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
  background: url("@{images}/white-sand.png");
}

编译后:

.banner {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
  background: url("../img/white-sand.png");
}
URLs

例子:

@images: "../img";

body {
  color: #444;
  background: url("@{images}/white-sand.png");
}

编译后:

body {
  color: #444;
  background: url("../img/white-sand.png");
}
导入声明

例子:

@themes: "../../src/themes";

@import "@{themes}/tidal-wave.less";
属性
@property: color;

.widget {
  @{property}: #0ee;
  background-@{property}: #999;
}

编译后:

.widget {
  color: #0ee;
  background-color: #999;
}

变量别名

@primary:  green;
@secondary: blue;

.section {
  @cc: primary;

  .element {
    color: @@cc;
  }
}

编译后:

@primary:  green;
@secondary: blue;

.section {
  @cc: primary;

  .element {
    color: @@cc;
  }
}

变量作为属性

例子:

.widget {
  color: #efefef;
  background-color: $color;

编译后:

.widget {
  color: #efefef;
  background-color: #efefef;
}

混合(Mixins)

混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black; 
}
#menu a { 
  color: #111; 
  .bordered(); 
}

除了使用.class,还可以使用#id

有参数的混合

例子:

.box(@position: absolute) {
  position: @position;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
div {
    .box(relative)
}

编译后:

div {
  position: relative;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

递归的混合

在栅格布局中(24 分栏),我们可能需要如下css代码:

.el-col-1 {
  /* 1/24 */
  width: 4.16667%;
}
.el-col-2 {
  /* 2/24 */
  width: 8.33333%;
}
.el-col-3 {
  /* 3/24 */
  width: 12.5%;
}
.el-col-4 {
  /* 4/24 */
  width: 16.66667%;
}
...

less代码如下:

.generate-col(@n, @i: 1) when (@i =< @n) {
    .el-col-@{i} {
        width: @i * (100% / 24);
    }
    .generate-col(@n, @i + 1)
}
.generate-col(24);

编译后:

.el-col-1 {
  width: 4.16666667%;
}
.el-col-2 {
  width: 8.33333333%;
}
.el-col-3 {
  width: 12.5%;
}
.el-col-4 {
  width: 16.66666667%;
}
.el-col-5 {
  width: 20.83333333%;
}
.el-col-6 {
  width: 25%;
}
.el-col-7 {
  width: 29.16666667%;
}
.el-col-8 {
  width: 33.33333333%;
}
.el-col-9 {
  width: 37.5%;
}
.el-col-10 {
  width: 41.66666667%;
}
.el-col-11 {
  width: 45.83333333%;
}
.el-col-12 {
  width: 50%;
}
.el-col-13 {
  width: 54.16666667%;
}
.el-col-14 {
  width: 58.33333333%;
}
.el-col-15 {
  width: 62.5%;
}
.el-col-16 {
  width: 66.66666667%;
}
.el-col-17 {
  width: 70.83333333%;
}
.el-col-18 {
  width: 75%;
}
.el-col-19 {
  width: 79.16666667%;
}
.el-col-20 {
  width: 83.33333333%;
}
.el-col-21 {
  width: 87.5%;
}
.el-col-22 {
  width: 91.66666667%;
}
.el-col-23 {
  width: 95.83333333%;
}
.el-col-24 {
  width: 100%;
}

混合守卫(Mixins Guards)

当我们想在表达式上匹配简单值或参数数量时,Guards 将会很有用。为了尽可能地保持 CSS 的声明性质,在 @media 查询特性规则中,Less 选择 Guards 函数的形式而不是 if/ else 语句来实现条件执行。

我们先来看一个使用when关键字作为条件的例子:

.mixin (@w; @h) when ( @w >= 100px) {
  font-size: 18px;
}

.mixin (@w; @h) {
  color: red;
}
.one{
  .mixin(150px, 50px);  
}
.two{
  .mixin(70px, 20px);
}

编译结果:

.one {
  font-size: 18px;
  color: red;
}
.two {
  color: red;
}

Guards比较运算符

Less 中包含五个 Guards 比较运算符,分别是>>===<<。关键字 true 是让两个 Mixins 等价的唯一真值,所以以下两个 Mixins 是等价的:

.mixin (@a) when (@a) { ... }
.mixin (@a) when (@a = true) { ... }

除了关键字 true,其他任何值都是假值:

.mixin (@a) when (@a) { 
  font-size: 14px;
 }
.one{
  .mixin(true);  // 只有 true 为真值
}
.two{
  .mixin(7);  // 其他任何值都是假值
}
// 编译后:
.one {
  font-size: 14px;
}

使用其他比较运算符:

.mixin (@a; @b) when (@a > @b) {
  width: @a 
}
.mixin (@a; @b) when (@a < @b) {
  width: @b 
}
.one{
  .mixin(10px, 20px);
}
.two{
  .mixin(200px, 100px);
}

编译后:

.one {
  width: 20px;
}
.two {
  width: 200px;
}
Guards逻辑运算符

当 Mixins 的判断条件含有两个或多个时,可以使用 Guards 逻辑运算符将条件进行关联。逻辑运算符有 andornot 三个。还可以使用 , 运算符来替代 or 。

and例子1:

.mixin(@color) when (iscolor(@color)) and (@color = red) { 
  color: @color;
}
.one{
  .mixin(red);
}
.two{
  .mixin(blue);
}

编译后:

.one {
  color: red;
}

or例子2:

.mixin (@w) when (@w >= 100px) or (@w <= 20px) { 
  width: @w;
}
.one{
  .mixin(120px);
}
.two{
  .mixin(10px);
}
.three{
    .mixin(80px);
}

编译后:

.one {
  width: 120px;
}
.two {
  width: 10px;
}

not例子3:

.mixin (@w) when not (@w = 0px) { 
  width: @w;
}
.one{
  .mixin(0px);
}
.two{
  .mixin(10px);
}
.three{
    .mixin(80px);
}

编译后:

.two {
  width: 10px;
}
.three {
  width: 80px;
}

嵌套(Nesting)

直接看代码:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

@规则嵌套和冒泡

@ 规则(例如 @media 或 @supports)可以与选择器以相同的方式进行嵌套。@ 规则会被放在前面,同一规则集中的其它元素的相对顺序保持不变。这叫做冒泡(bubbling)。

.component {
  width: 300px;
  @media (min-width: 768px) {
    width: 600px;
    @media  (min-resolution: 192dpi) {
      background-image: url(/img/retina2x.png);
    }
  }
  @media (min-width: 1280px) {
    width: 800px;
  }
}

编译后:

.component {
  width: 300px;
}
@media (min-width: 768px) {
  .component {
    width: 600px;
  }
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
  .component {
    background-image: url(/img/retina2x.png);
  }
}
@media (min-width: 1280px) {
  .component {
    width: 800px;
  }
}

父级选择器

父级选择器的引用使用$表示

.button {
  &-ok {
    background-image: url("ok.png");
  }
  &-cancel {
    background-image: url("cancel.png");
  }

  &-custom {
    background-image: url("custom.png");
  }
}

编译后:

.button-ok {
  background-image: url("ok.png");
}
.button-cancel {
  background-image: url("cancel.png");
}
.button-custom {
  background-image: url("custom.png");
}
多个$使用

例子1:

.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;
}

例子2:

.grand {
  .parent {
    & > & {
      color: red;
    }
    & & {
      color: green;
    }
    && {
      color: blue;
    }
    &, &ish {
      color: cyan;
    }
  }
}

编译后:

.grand .parent > .grand .parent {
  color: red;
}
.grand .parent .grand .parent {
  color: green;
}
.grand .parent.grand .parent {
  color: blue;
}
.grand .parent,
.grand .parentish {
  color: cyan;
}

改变选择器的顺序

.header {
  .menu {
    border-radius: 5px;
    .no-borderradius & {
      background-image: url('images/button-background.png');
    }
  }
}

编译后:

.header .menu {
  border-radius: 5px;
}
.no-borderradius .header .menu {
  background-image: url('images/button-background.png');
}

排列组合

p, a, ul, li {
  border-top: 2px dotted #366;
  & + & {
    border-top: 0;
  }

编译后:

p,
a,
ul,
li {
  border-top: 2px dotted #366;
}
p + p,
p + a,
p + ul,
p + li,
a + p,
a + a,
a + ul,
a + li,
ul + p,
ul + a,
ul + ul,
ul + li,
li + p,
li + a,
li + ul,
li + li {
  border-top: 0;
}

运算(Operations)

算术运算符 +-*/ 可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。

// 所有操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm

// 不同单位的加减
@incompatible-units: 2 + 5px - 3cm; // 结果是 4px

// 变量的运算
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%

// 乘法和除法不作转换
@base: 2cm * 3mm; // 结果是 6cm

@var: 50vh/2; width: calc(50% + (@var - 20px)); // 结果是 calc(50% + (25vh - 20px))

为了与 CSS 保持兼容,calc() 并不对数学表达式进行计算,但是在嵌套函数中会计算变量和数学公式的值。

@var: 50vh/2;
width: calc(50% + (@var - 20px)); // 结果是 calc(50% + (25vh - 20px))

转义(Escaping)

转义(Escaping)允许你使用任意字符串作为属性或变量值。任何 ~"anything" 或 ~'anything' 形式的内容都将按原样输出,除了插值变量。

例子:

@min768: ~"(min-width: 768px)";
.element {
  @media @min768 {
    font-size: 1.2rem;
  }
}

编译后:

@media (min-width: 768px) {
  .element {
    font-size: 1.2rem;
  }
}

映射(Maps)

直接看代码:

#colors() {
  primary: blue;
  secondary: green;
}

.button {
  color: #colors[primary];
  border: 1px solid #colors[secondary];
}

函数

逻辑函数系列

if

参数:

  • condition:布尔表达式
  • value1: 布尔表达式为true时的返回值
  • value2: 布尔表达式不为true时的返回值

例子:

@some: foo;
div {
  margin: if((2 > 1), 0, 3px);
}

编译后:

div {
  margin: 0;
}

boolean

参数:

  • condition:布尔表达式

例子:

@bg: black;
@bg-light: boolean(luma(@bg) > 50%);
div {
  background: @bg;
  color: if(@bg-light, black, white);
}

编译后:

div {
  background: black;
  color: white;
}

String 函数系列

escape

参数: string: 字符串 使用URL-encoding的方式编码字符串。常用于对url中出现= \ / ; ^等字符进行编码。

如果参数是字母表中26个字母,大小写均可,或者是数字,则原样返回。

不会被编码的字符:/ ? @ & + ' ~ ! $

常见的被编码的字符串:# ^ ( ) { } | : > < ; [ ] =

例子:

escape('a=1')

编译后:

escape('a=1')

e

用于对CSS的转义,其接收一个字符串作为参数,并原样返回内容(不含字符串的两边的引号)。可用于输出一些不合法的CSS语法,或者是使用LESS不能识别的属性。使得这样不会报错,虽然输出样式和原来的没有区别,但是具体的内容被进行了处理。

例子:

@myurl: e("a=1&b>100");
#header {
  background-image: url(@myurl);
}

编译后:

#header {
  background-image: url(a=1&b>100);
}

%

函数 %(string, arguments ...) 格式化一个字符串。

第一个参数是包含占位符的字符串。所有的占位符以%开头,后跟着的说明符包括:s,S,d,D,a或 A

例子:

@bg: %('gggg%d', #fff);
@bg2: %('gggg%s', '111');
@bg3: %('gggg%d', '111');
div {
  background: @bg;
}
p {
  background: @bg2;
}
.box {
    background: @bg3;
}

编译后:

div {
  background: 'gggg#fff';
}
p {
  background: 'gggg111';
}
.box {
  background: 'gggg'111'';
}

replace

参数:

  • string:要搜索和替换的字符串。
  • pattern:要搜索的字符串或正则表达式模式。
  • replacement:要用来替换匹配模式的字符串。
  • flags:(可选)正则表达式标志。

例子:

.box1::after {
  content: replace("Hello, Mars?", "Mars\?", "Earth!");
}
.box2::after {
  content: replace("One + one = 4", "one", "2", "gi");
}
.box3::after {
  content: replace('This is a string.', "(string)\.$", "new $1.");
}
.box4::after {
  content: replace(~"bar-1", '1', '2');
}

编译后:

.box1::after {
  content: "Hello, Earth!";
}
.box2::after {
  content: "2 + 2 = 4";
}
.box3::after {
  content: 'This is a new string.';
}
.box4::after {
  content: bar-2;
}

List函数系列

length

返回列表中元素的数量

参数:

  • list:一个采用逗号/空格隔开的列表
@list1: "a" "b" "c" "d";
@list2: "a","b";
div {
  width: length(@list1)px;
  height: length(@list2)px;
}

编译后:

div {
  width: 4 px;
  height: 2 px;
}

extract

返回指定位置上的索引的值, index从1开始

参数:

  • list: 一个采用逗号/空格隔开的列表
  • index: 列表中指定位置上的索引

例子:

@list: 1, 2, 4, 8;
.box {
    width: extract(@list, 4) * 10px;
}

编译后:

.box {
  width: 80px;
}

range

生成一个包含一系列值的列表。

参数:

  • start: (可选) 开始值
  • end: 结束值
  • step: (可选) 步长

例子:

@v: range(10px, 40px, 10px);
.box {
    padding: @v;
}

编译后:

.box {
  padding: 10px 20px 30px 40px;
}

each

参数:

  • list - 一个采用逗号/空格隔开的列表
  • rules - 一个匿名的规则集或混入

例子1:

@selectors: blue, green, red;

each(@selectors, {
  .sel-@{value} {
    a: b;
  }
});

编译后:

.sel-blue {
  a: b;
}
.sel-green {
  a: b;
}
.sel-red {
  a: b;
}

例子2:

@set: {
  one: blue;
  two: green;
  three: red;
}
.set {
  each(@set, {
    @{key}-@{index}: @value;
  });
}

编译后:

.set {
  one-1: blue;
  two-2: green;
  three-3: red;
}

例子3:

each(range(4), {
  .col-@{value} {
    height: (@value * 50px);
  }
});

编译后:

.col-1 {
  height: 50px;
}
.col-2 {
  height: 100px;
}
.col-3 {
  height: 150px;
}
.col-4 {
  height: 200px;
}

Math函数系列

ceil

向上取整

floor

向下取整

percentage

将小数转化为百分比的形式

round

四舍五入 参数:

  • number:浮点数
  • decimalPlaces: 可选参数,四舍五入取整的小数点位置,默认值为0

sqrt

计算数字的平方根

abs

求数字的绝对值

pow

求幂

  • number: 底
  • number: 幂

mod

取模

Type函数系列

isnumber

判断值是否是数字

isstring

判断值是否是字符串

iscolor

判断值是否是颜色值

iskeyword

判断值是否是关键字

isurl

判断值是否是一个url地址,该地址需要放在url函数中,而不是单纯的一个字符串

ispixel

判断值是否是带像素单位的值

isem

判断值是否是带em单位的值

ispercentage

判断值是否是带百分比单位的值

isunit

判断值是否是带指定单位的值

其他杂项函数

color

将代表颜色的字符串(内置颜色值:red等,以及十六进制值)转换为十六进制颜色值。rgb值还是转换为rgb值。

例子:

@color: red;
@colorborder: rgba(0,3,4,.5);
div {
  background: color(@color);
  border: 1px solid color(@colorborder);
}

编译后:

div {
  background: #ff0000;
  border: 1px solid rgba(0, 3, 4, 0.5);
}

convert

数据兼容单位之间的转换。

兼容单位有:

长度: mcmmminptpc

时间: sms

角度: raddeggradturn

第一个参数是带单位的数值,第二个参数是要转换的单位。如果两个参数的单位是兼容的,则数字的单位被转换,如果两个参数的单位不兼容,则原样返回第一个参数。

data-url

将资源文件内嵌到样式文件中。

例子:

@bg: '/images/dog.jpg';
div {
  background-image: data-uri(@bg);
}

编译后:

div {
  background-image: url('/images/dog.jpg');
}

default

边界函数,当自定义函数都不匹配的时候,该默认函数被匹配,否则匹配匹配成功的函数。

// 定义了三个自定义函数
.minx(1) {
  x: 2;
}
.minx(2) {
  x: 3;
}
.minx(@x) when(default()) {
  z:@x;
}
div {
    // 匹配成功
  .minx(1);
}
span {
    // 匹配成功
  .minx(2);
}
.my {
    // 匹配不成功 匹配默认函数
  .minx(3);
}

编译后:

div {
  x: 2;
}
span {
  x: 3;
}
.my {
  z: 3;
}

unit

移除或者改变属性值的单位

第一个参数是要做计算的数据,可以带单位或者不带单位,如果不带单位且第二个参数有值,则会加上,否则替换。

第二个参数是可选值,将要替换的单位。

例子: unit(5, px) 结果: 5px

例子: unit(5em) 结果: 5

color函数系列

rgb

将rgb颜色值转为十六进制颜色值

参数:

  • red: 整数 0-255 或者百分比 0-100%
  • green: 整数0-255 或者百分比 0-100%
  • blue: 整数0-255 或者百分比 0-100%

lightness

提取lightness亮度

div {
  background-color: lightness(#909090);
}

编译后:

div {
  background-color: 56.47058824%;
}

red(@color)

提取red颜色的值

green(@color)

提取green颜色的值

blue(@color)

提取blue颜色的值

alpha(@color)

提取透明度的值

lighten(@color,10%)

提高10%的@color亮度

darken(@color,10%)

降低10%的@color

fadein(@color,10%)

透明度增加10%

fadeout(@color,10%)

透明度减少10%

fade(@color,10%)

设置透明度为10%

其他更多funciton 参考Less内置函数