less使用指南
Less预处理语言学习笔记
Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。它能够以更灵活的方式去编写CSS,同时能够更加方便的管理CSS/Less
注释
以//开头的单行注释不会被编译到css文件中
// 不会被编译到css文件中
被/**/包裹的多行注释会被编译到css文件中
/*
会被编译到css文件中
*/
变量
less中定义变量的语法:
// 定义普通变量
@var_name: var_value;
// 定义引用变量
@var1: blue;
@color: @var1;
// 定义可变变量
@var1: red;
@variable_variables: var1;
less中使用变量的几种方法:
-
当变量作为属性值使用(最为常用的方式)
@color1: blue; .father { color: @color1; }
编译后:
.father { color: blue; }
-
当变量作为属性名使用
@prop: background-color; .father { @{prop}: #bfa; }
编译后:
.father { background-color: #bfa; }
-
当变量作为CSS选择器使用
@selector: #father; @{selector} { color: #bfa; }
编译后:
#father { color: #bfa; }
-
引入字符串(路径)
@url: "https:www.google.com"; #father { background-image: url("@{url}"); }
编译后:
#father { background-image: url("https:www.google.com"); }
-
引入less文件(类似于module)
@file_path: "./index.less"; @import @{file_path};
编译后:
<!-- 相当于将./index.less中所有的less"复制"到当前的less文件中 -->
-
使用引用变量
@var1: blue; @color: @var1; #father { color: @color; }
编译后:
#father { color: blue; }
-
使用可变变量
@var1: blue; #father { @variable_variables: var1; .son { color: @@variable_variables; } }
编译后:
#father .son { color: blue; }
less中变量的延迟加载:
延迟加载机制可以认为等价于js中的中的var变量的变量提升
#father {
@color: red;
color: @color; // blue
@color: blue;
}
属性名作为变量:
less新添加功能, 可以通过属性名作为变量取得其值; 该机制类似于使用引用变量或可变变量
/* 属性名作为变量 */
#father {
color: blue;
.son {
background-color: $color; // blue
}
}
/* 可变变量 */
@var1: blue;
@color: @var1;
#father {
color: @color;
.son {
background-color: @color; // blue
}
}
/* 可变变量 */
@variable_variables: blue;
#father {
@color: variable_variables;
.son {
background-color: @@color; // blue
}
}
编译为:
/* 属性名作为变量 */
#father {
color: blue;
}
#father .son {
background-color: blue;
}
/* 可变变量 */
#father {
color: blue;
}
#father .son {
background-color: blue;
}
/* 可变变量 */
#father .son {
background-color: blue;
}
嵌套规则
less中嵌套的语法规则主要靠&
实现
选择器为父子关系时的嵌套
.father {
color: red;
.son {
color: blue;
}
}
编译后:
.father {
color: red;
}
.son {
color: blue;
}
交集选择器/伪类/伪元素的嵌套
/* 交集选择器 */
.cls1 {
color: red;
&.cls2 {
font-size: 12px;
}
}
/* 伪类 */
.pesudo-cls {
&:hover {
color: red;
}
}
/* 伪元素 */
.pesudo-ele {
&:first-child {
color: red;
}
}
编译后:
/* 交集选择器 */
.cls1 {
color: red;
}
.cls1.cls2 {
font-size: 12px;
}
/* 伪类 */
.pesudo-cls:hover {
color: red;
}
/* 伪元素 */
.pesudo-ele:first-child {
color: red;
}
多重&
其原理将&
看做是一个变量, 变量值是父选择器
.father {
& + & {
color: red;
}
& > & {
color: green;
}
& ~ & {
color: blue;
}
&& {
color: #bfa;
}
&[title=Fitz] {
color: pink;
}
& > &_and_son {
color: orange;
}
}
编译后:
.father + .father {
color: red;
}
.father > .father {
color: green;
}
.father ~ .father {
color: blue;
}
.father.father {
color: #bfa;
}
.father[title=Fitz] {
color: pink;
}
.father > .father_and_son {
color: orange;
}
通过&改变选择器顺序
原理同样是将&
看做一个变量, 变量值为该父选择器
.father {
.son {
color: pink;
}
// 使用&改变顺序
.son & {
color: red;
}
}
编译后:
.father .son {
color: pink;
}
.son .father {
color: red;
}
组合爆炸
在有多个选择器的情况下,利用多重&
的原理对选择器进行两两组合(自身与自身也可以进行组合), 从而最终产生n^2个组合(n为选择器个数)
// 将会产生3^2=9个组合
.a, .b, .c {
& & {
color: red;
}
}
编译后:
.a .a,
.a .b,
.a .c,
.b .a,
.b .b,
.b .c,
.c .a,
.c .b,
.c .c {
color: red;
}
混合(mixins)
less的混合就是将一系列CSS规则集引入另一个规则集中, mixins的作用与function相似, 都体现了复用的思想
语法:
.混合名 {
// 样式集
}
普通混合
.clearfix {
content: '';
clear: both;
display: table;
}
.father {
color: red;
/* 使用mixins */
.clearfix();
}
编译后:
.clearfix {
content: '';
clear: both;
display: table;
}
.father {
color: red;
/* 使用mixins */
content: '';
clear: both;
display: table;
}
混合不输出到编译出的CSS中(不带输出的混合)
是对普通混合的优化, 能够使得编译出的css文件中不会出现混合
.clearfix() {
content: '';
clear: both;
display: table;
}
.father {
color: red;
/* 使用mixins */
.clearfix();
}
编译后:
.father {
color: red;
/* 使用mixins */
content: '';
clear: both;
display: table;
}
带参数的混合
.set_Color(@color) {
color: @color;
}
.father {
.set_Color(orange);
}
编译后:
.father {
color: orange;
}
带参数且参数有默认值的混合
.set_style(@color: red) {
color: @color;
}
.father {
.set_style();
}
.uncle {
.set_style(pink)
}
编译后:
.father {
color: red;
}
.uncle {
color: pink;
}
编译后:
带多个参数的混合
.set_style(@color: red, @font-size: 16px) {
color: @color;
font-size: @font-size;
}
.father {
.set_style(orange);
}
.uncle {
.set_style(pink, 12px)
}
编译后:
.father {
color: orange;
font-size: 16px;
}
.uncle {
color: pink;
font-size: 12px;
}
命名关键字参数混合
.test(@color: red, @width, @height) {
color: @color;
width: @width;
height: @height;
}
.father {
.test(@height: 50px, @width: 100px)
}
编译后:
.father {
color: red;
width: 100px;
height: 50px;
}
匹配模式
有时可能想根据传递的参数来更改混合的行为时就可以使用混合中的匹配模式
语法:
.pattern-match-name(identifier, @parm1, @parm...) {
/* 样式集 */
}
.direction(LEFT, @direct: left) {
position: absolute;
@{direct}: 100px;
}
.direction(RIGHT, @direct: right) {
position: absolute;
@{direct}: 100px;
}
.direction(TOP, @direct: top) {
position: absolute;
@{direct}: 100px;
}
.direction(BOTTOM, @direct: bottom) {
position: absolute;
@{direct}: 100px;
}
// 使用匹配模式
.father {
.direction(TOP)
}
编译后:
.father {
position: absolute;
top: 100px;
}
当匹配模式中的样式集重复度较高时, 可以进一步对样式进行抽离
当标识符为@_
时, 它会被mix到所有同名的mixins中
/*
当标识符为`@_`时, 它会被mix到所有同名的mixins中
*/
.direction(@_) {
position: absolute;
}
.direction(LEFT, @direct: left) {
@{direct}: 100px;
}
.direction(RIGHT, @direct: right) {
@{direct}: 100px;
}
.direction(TOP, @direct: top) {
@{direct}: 100px;
}
.direction(BOTTOM, @direct: bottom) {
@{direct}: 100px;
}
// 使用匹配模式
.father {
.direction(TOP)
}
编译后:
.father {
position: absolute;
top: 100px;
}
arguments变量
less中的@arguments
与js中的arguments参数作用一致, 都是代表所有传入的参数
.test_arguments(@width, @style, @color) {
border: @arguments;
background-color: @color;
}
.father {
.test_arguments(1px, solid, orange);
}
.son {
background: .test_arguments(1px, solid, orange)[background-color];
}
编译后:
.father {
border: 1px solid orange;
background-color: orange;
}
.son {
background: orange;
}
命名空间模式
命名空间模式能够有效的防止less的命名空间污染, 即这样一种情况: 通过@import
引入的两个less中都有叫fix_bug
的混合
// 定义两个less库
#library1() {
.fix_bug {
color: red;
}
}
#library2() {
.fix_bug {
color: yellow;
}
}
.father {
#library1.fix_bug();
}
.son {
#library2.fix_bug();
}
编译后:
.father {
color: red;
}
.son {
color: yellow;
}
混合改名(alias)
用于解决命名冲突
// 定义两个less库
#library1() {
.fix_bug {
color: red;
}
}
#library2() {
.fix_bug {
color: yellow;
}
}
// 下面这一步不是必要的
.libs() {
@method1: #library1.fix_bug();
@method2: #library2.fix_bug();
}
.father {
@get_method: .libs[@method1];
@get_method();
}
.son {
@get_method: .libs[@method2];
@get_method();
}
编译后:
.father {
color: red;
}
.son {
color: yellow;
}
多重混合
.container() {
.set_style(@color) {
words_color: @color;
background-color: @color;
}
}
.father {
color: .container.set_style(red)[words_color];
}
.son {
background-color: .container.set_style(orange)[background-color];
}
编译后:
.father {
color: red;
}
.son {
background-color: orange;
}
混合中的闭包
// 定义两个less库
#library1() {
.fix_bug {
color: red;
}
}
#library2() {
.fix_bug {
color: yellow;
}
}
@cloure1: #library1.fix_bug();
@cloure2: #library2.fix_bug();
.father {
@cloure1();
}
.son {
@cloure2();
}
编译后:
.father {
color: red;
}
.son {
color: yellow;
}
综合比较几种容易混淆的混合使用方法
第一种:
.libs() {
.set_color(@color) {
color: @color;
}
}
.use_mixins {
.libs.set_color(pink);
}
//=============================
.use_mixins {
color: pink;
}
第二种:
.libs() {
favourite_color: orange;
needed_size: 12px;
}
.use_mixins {
color: .libs[favourite_color];
}
.use_mixins2 {
font-size: .libs[needed_size];
}
//===================
.use_mixins {
color: orange;
}
.use_mixins2 {
font-size: 12px;
}
第三种:
.libs() {
color: orange;
font-size: 16px;
}
.pkg {
@method: .libs();
}
.use_mixins {
@get_method: .pkg[@method];
@get_method();
}
//=====================
.use_mixins {
color: orange;
font-size: 16px;
}
less的作用域
先在自己的作用域查找, 找不多就去父级作用域中查找
#scope {
@color: red;
#inner_scope {
@color: green;
color: @color; // green
}
}
#scope {
@color: red;
#inner_scope {
#inner_scope2 {
color: @color; // blue
}
@color: blue; // 变量的懒加载
}
}
编译后:
#scope #inner_scope {
color: green;
}
#scope #inner_scope #inner_scope2 {
color: blue;
}
@media规则的冒泡
@media
可以嵌套在规则集中, 但是编译后会冒泡到规则集的最开始
@min: 778px;
@max: 1080px;
.bubble {
@media (min-width: @min) and (max-width: @max) {
color: red;
}
}
编译后:
@media (min-width: 778px) and (max-width: 1080px) {
.bubble {
color: red;
}
}
运算
less中可以对数值进行运算
运算结果以最左侧有单位的target为准
.father {
width: 10px + 10em + 10; // 30px
}
.son {
width: 10 + 10em + 10; // 30em
}
编译后:
.father {
width: 30px;
}
.son {
width: 30em;
}
对于calc()
由于CSS中已经有该函数, 所以less会原封不动的对其进行编译, 将计算交给CSS, 不影响less本身的变量计算
@max-width: 10px;
.son {
width: calc(10px * 20);
}
.son2 {
width: calc((@max-width + 20px) * 10);
}
编译后:
.son {
width: calc(10px * 20);
}
.son2 {
width: calc((10px + 20px) * 10);
}
extend(继承)
当多个CSS样式集中有大量重复时, 我们可以进行样式抽离, 从而减轻CSS体积
.rule1 {
width: 100px;
height: 100px;
background-color: red;
}
.rule2 {
width: 100px;
height: 100px;
background-color: yellow;
}
.rule3 {
width: 100px;
height: 100px;
background-color: blue;
}
/* 优化后 */
.rule1,
.rule2,
.rule3 {
width: 100px;
height: 100px;
}
.rule1 {
background-color: red;
}
.rule2 {
background-color: yellow;
}
.rule3 {
background-color: blue;
}
extend的语法:
.a:extend(.b)
与.a{&:extend(.b)}
等价于CSS:
.b,
.a{
}
// extend有以下两种语法
.name:extend(.extend_styleSet_name) {}
.name {
&:extend(.extend_styleSet_name);
}
注意区别被extend的样式集和mixins:
被extend的样式集不能添加()否则extend功能将失效
.mixins() {
color: red;
}
.be_extended() { // 添加括号
color: green;
}
/* ============= 使用 =============== */
.use_mixins {
.mixins();
}
.use_extend {
&:extend(.be_extended);
}
编译后:
/* ============================ */
.use_mixins {
color: red;
}
所以extend的使用不能添加括号:
.mixins() {
color: red;
}
.be_extended { // 不能添加括号
color: green;
}
/* ============= 使用 =============== */
.use_mixins {
.mixins();
}
.use_extend {
&:extend(.be_extended);
}
编译后:
.be_extended,
.use_extend {
color: green;
}
/* ============================ */
.use_mixins {
color: red;
}
使用示例:
.md {
position: relative;
top: 0;
left: 0;
}
.xs {
.lg:extend(.md) {
color: purple;
}
}
.xs2 {
.lg {
&:extend(.md);
color: purple;
}
}
编译后:
.md,
.xs .lg,
.xs2 .lg {
position: relative;
top: 0;
left: 0;
}
.xs .lg {
color: purple;
}
.xs2 .lg {
color: purple;
}
当被extend
的样式集中有&
等平级样式时, 如:hover伪类
, extend()
需要添加一个all
实参才能继承,否则会忽略&
后面的样式集
没有传入实参all
.be_extended {
position: relative;
top: 0;
left: 0;
&:hover {
color: black;
}
&:first-child {
font-size: 10px;
}
}
.md {
&:extend(.be_extended);
}
编译后:
.be_extended,
.md {
position: relative;
top: 0;
left: 0;
}
.be_extended:hover {
color: black;
}
.be_extended:first-child {
font-size: 10px;
}
传入实参all
后:
.be_extended {
position: relative;
top: 0;
left: 0;
&:hover {
color: black;
}
&:first-child {
font-size: 10px;
}
}
.md {
&:extend(.be_extended all);
}
编译后:
.be_extended,
.md {
position: relative;
top: 0;
left: 0;
}
.be_extended:hover,
.md:hover {
color: black;
}
.be_extended:first-child,
.md:first-child {
font-size: 10px;
}
转义escaping
当需要less原封不动(不进行编译)输出某些值时, 需要用到转义
@c: 100px;
.escaping {
width: ~"calc(10px + c * 10)"; /* width: calc(10px + c * 10); */
}
编译后:
.escaping {
width: calc(10px + c * 10);
/* width: calc(10px + c * 10); */
}
使用~""
进行转义对变量插值无效
什么是变量插值:
@var: width;
@var2: './index.less';
.father {
@{var}: 100px;
}
@import "@{var2}";
示例:
@c: 100px;
.when_use_interpolation_escaping_not_word {
width: ~"calc(10px + @{c} * 10)"; /* width: calc(10px + 100px * 10); */
}
编译后:
.when_use_interpolation_escaping_not_word {
width: calc(10px + 100px * 10);
/* width: calc(10px + 100px * 10); */
}
映射Maps
本质上就是将mixins当做对象使用
.father() {
color: red;
font-size: 20px;
}
.use_maps {
background-color: .father[color];
}
.use_maps2 {
line-height: .father[font-size];
}
编译后:
.use_maps {
background-color: red;
}
.use_maps2 {
line-height: 20px;
}
当属性是使用变量的插值法时, Maps要显式指定属性名而不是变量名
@favourite_style: font-size;
.father {
@{favourite_style}: 18px;
}
// 错误的maps使用方法
.use_maps {
line-height: .father[@{favourite_style}]; // 编译错误
}
// 正确的maps使用方法
.use_maps {
line-height: .father[font-size]; // line-height: 18px;
}