ZHANGYU.dev

October 14, 2023

Less学习笔记(一)基本语法

CSS5.3 min to read

一直以来用的都是scss,最近开发Ant Design Pro需要使用less,记录学习笔记

变量

声明

Less里用@开头声明变量

@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

输出

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

变量插值 Variable Interpolation

// Variables
@my-selector: banner;
@property: color;

// Usage
.@{my-selector} {
  @{property}: #0ee;
  background-@{property}: #999;
}

输出

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

将属性作为变量

也就是说可以使用$prop的形式,来引用

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

输出

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

默认变量

// library
@base-color: green;
@dark-color: darken(@base-color, 10%);

// use of library
@import "library.less";
@base-color: red;

根据LessLazy Loading,我们声明的变量可以覆盖之前的,并且library中的@dark-color变成了深红色,因为@base-color已经是红色的了

父级选择器

常规用法

a {
  color: blue;
  &:hover {
    color: green;
  }
}

输出

a {
  color: blue;
}

a:hover {
  color: green;
}

类名组合

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

输出

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

多次使用&

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

更改选择器顺序

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

继承 Extend

ExtendLess中的一个伪类

nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}
// 这种方式也是相同的效果
nav ul:extend(.inline) {
  background: blue;
}

输出

nav ul {
  background: blue;
}
.inline,
nav ul {
  color: red;
}

也就是让当前的nav ul也有了.inlinecolor:red属性

可以使用逗号来继承多个类

.e:extend(.f, .g) {}

all关键字

不带all关键字的继承

.a{
  color:red;
  .b{
    font-size:24px;
  }
}
.d{
  &:extend(.b);
}

输出

.a {
  color: red;
}
.a .b {
  font-size: 24px;
}

可以看到结果最后是没有继承.b的,如果添加了all关键字,就会带上选择器层级一起继承

.a{
  color:red;
  .b{
    font-size:24px;
  }
}
.d{
  &:extend(.b all); // all 关键字
}

输出

.a {
  color: red;
}
.a .b,
.a .d {
  font-size: 24px;
}

合并 Merge

合并可以将多个属性值合并在一起

在属性名后加上+,属性值会以逗号分隔合并

.mixin() {
  box-shadow+: inset 0 0 10px #555;
}
.myclass {
  .mixin();
  box-shadow+: 0 0 20px black;
}

输出

.myclass {
  box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

在属性名后加上+_,属性值会以空格合并

.mixin() {
  transform+_: scale(2);
}
.myclass {
  .mixin();
  transform+_: rotate(15deg);
}

输出

.myclass {
  transform: scale(2) rotate(15deg);
}

混入 Mixins

从已经存在的styles中混入

如果不希望创建的mixin转译为CSS,可以在名字后面加上空格

.my-mixin {
  color: black;
}
.my-other-mixin() {
  background: white;
}
.class {
  .my-mixin();
  .my-other-mixin();
}

输出

.my-mixin {
  color: black;
}
.class {
  color: black;
  background: white;
}

Mixins不仅可以包含属性,还可以包含选择器

.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}
button {
  .my-hover-mixin();
}

输出

button:hover {
  border: 1px solid red;
}

可以从多层级的选择器中只继承一个

#my-library {
  background:red;
  .my-mixin {
    color: black;
  }
}
.class {
  // 只想继承color
  #my-library.my-mixin();
}

输出

#my-library {
  background: red;
}
#my-library .my-mixin {
  color: black;
}
.class {
  color: black;
}

带参数的Mixins

这里就稍微复杂一点

.mixin(@color) {
  color-1: @color;
}
// 带默认参数
.mixin(@color; @padding: 2) {
  color-2: @color;
  padding-2: @padding;
}
.mixin(@color; @padding; @margin: 2) {
  color-3: @color;
  padding-3: @padding;
  margin: @margin @margin @margin @margin;
}
.some .selector div {
  .mixin(#008000);
}

具有相同名字的mixin是合法的,同时匹配所有符合条件的mixin

所以输出为

.some .selector div {
  color-1: #008000;
  color-2: #008000;
  padding-2: 2;
}

只传入了一个参数,匹配1个参数的mixin和1个参数1个含默认值的参数的mixin

命名参数

.mixin(@color: black; @margin: 10px; @padding: 20px) {
  color: @color;
  margin: @margin;
  padding: @padding;
}
.class1 {
  .mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
  .mixin(#efca44; @padding: 40px);
}

传参时可以对参数命名代表要传入的参数

输出

.class1 {
  color: #33acfe;
  margin: 20px;
  padding: 20px;
}
.class2 {
  color: #efca44;
  margin: 10px;
  padding: 40px;
}

@arguments变量

@arguments变量表示了传入的所有参数

.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
	box-shadow: @arguments;
}
.big-block {
  .box-shadow(2px; 5px);
}

输出

.big-block {
	box-shadow: 2px 5px 1px #000;
}

将Mixins当作函数使用

可以从mixin的调用中获取属性和值

.average(@x, @y) {
  @result: ((@x + @y) / 2);
}

#library() {
  .mixin() {
    prop: foo;
  }
}

div {
  // 调用.average并从中获取@result的值
  padding: .average(16px, 50px)[@result];
  my-value: #library.mixin[prop];
}

输出

div {
  padding: 33px;
  my-value: foo;
}

如果[]内不写值,则会取最后一个属性的值

.average(@x, @y) {
  @result: ((@x + @y) / 2);
  @result1: ((@x + @y) / 10);
}

div {
  // call a mixin and look up its final value
  padding: .average(16px, 50px)[];
}

输出

div {
  padding: 6.6px;
}

递归/循环 Mixins

递归

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // 下一次迭代
  width: (10px * @counter); // 每次迭代的代码
}

div {
  .loop(5); // 递归5次
}

输出

div {
  width: 10px;
  width: 20px;
  width: 30px;
  width: 40px;
  width: 50px;
}

属性/变量 访问符

@config: {
  @colors: {
    primary: blue;
  }
}

.box {
  color: @config[@colors][primary];
}

输出

.box {
  color: blue;
}

u1s1,快看吐了

为什么写一个CSS都已经复杂到了可以写递归的地步呢?

平时用预处理器,也就是嵌个套,用一下Mixins的功能,学了这么多功能也不一定用得上,难道以后除了看JS源码,连CSS的源码也要看了😂