镇楼图

Pixiv:战争子
注:此blog至少建立在一定的CSS基础之上,其中选择器更加重要
〇、LESS(Leaner Style Sheets)是什么?
是CSS的预处理器,因为CSS编写起来确实特别麻烦,因此有了CSS预处理器的工具来简化编写代码时间
其他比较有名的CSS预处理还有SASS、SCSS、Stylus
引入
<link rel="stylesheet/less" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.11.1/less.min.js" ></script>
<!-- 浏览器环境,引入Less.js,或者自己下载Less.js -->
npm install -g less
> lessc styles.less styles.css
<!-- Node.js环境 -->
由于LESS仅仅加了些许扩展,因此学习起来很简单,这也是为什么CSS的blog还没写完我先写LESS的情况。不必担心兼容性,LESS几乎支持一切浏览器
问题一:如果在客户端环境下使用或多或少必然会有一定上性能的消耗
问题二:LESS由于使用了Ajax必须必须在http(s)协议下使用,直接本地文件执行js文件是不会有任何效果的!!!!!
Koala
可以下载Koala用于将Less文件转译成css文件,由此可以使用生成的css文件而不必使用less文件也能避免上述所说的问题
但是需要注意LESS在Koala里的版本是非常低的,为了避免因版本导致的错误,建议您安装nodejs后安装less,具体安装步骤这里就不再阐述了

LESS文件编写
首先创建个less后缀的文件,然后和CSS一样就可以开始写LESS加持的代码了
但需要注意每个.less文件是独立编译的,其中的任何定义的东西都是不可相互访问的,也就是1.less中定义的变量不可以在2.less中访问
一、变量
尽管在CSS3中也存在变量机制,但其支持可能并不如LESS
变量定义属性值
变量可以去定义属性值,以【@变量名】的形式定义,调用属性值也是【@变量名】
@width: 10px;
@height: 50px;
.father {
width: @width;
height: @height;
}
个人理解:@指针
变量本身是通过@去定义的,其中@可以理解为指针
对上一个例子稍加改动可以很直观地说明这个问题
@width: 10px;
@height: 50px;
.father {
width: width;
height: @height;
}
当我用koala编译后它的结果如下图
其中加了@的被解成了50px,没加@的就是其原样
在下面变量定义变量能感受这种类似于指针的用法
指针与变量赋值
变量同样可以作为其他变量的变量
@color1: grey;
@color3: color1;
//不加@就是其本身
p{
color: @@color3;
//color3就是color3
//@color3被解成了color1
//@@color3被解成了grey
}
但是LESS似乎只支持到两层@,当博主尝试@@@时报错了
在理解变量的本质后应该知道如何去赋值变量
@color1: grey;
@color3: @color1;
//加@就是其属性值从而完成赋值操作
p{
color: @color3;
}
个人理解:$解引用(v3.0.0)
在新版本3.0.0下可以使用$符号来解引用一个要作为样式的属性
在某些情况下可能更加节省代码量。
我个人认为这种语法适用于“同类属性”的情况,所谓同类属性是指功能性一样但应用范围不同,如下例的color、background-color都是用于颜色设置只不过一个是文字一个是背景罢了
div {
margin: 0px;
padding: $margin;
color: #fff;
background-color: $color;
//解引用无需定义新的变量
}
基于上面@假设为指针的理解,这里我理解为解引用,但理解归理解,实际操作和之前指针一样无法实现理解上的语法
变量定义属性名和部分属性名(v1.6.0)
除了属性值以外变量还可以定义很多内容,其中只要不是去定义属性值或是变量的,在调用时必须以【@{变量名}】的形式去调用
LESS不像正统语言一样有严格的语法规范,有些看上去可能符合猜想的语法都会报错
@p1: color;
.father {
@{p1}: red;
}
此外还可以去定义部分属性名,很多CSS属性会用-
符号区分这时候可以通过LESS这样定义
@v: left;
.div1 {
margin-@{v}: 0;
}
变量定义选择器(V1.4.0)
@firbox: father;
@element: a;
.@{firbox} > @{element}[data-v="1"]:visited {
color: red;
}
变量定义url(的一部分)(v1.4.0)
由于url网址部分一般都是会有相同的前缀部分,也可以定义url字符串在url里使用
@images: "../images";
html {
background: url("@{images}/1.jpg");
}
变量作用域(Lazy evaluation)
只要保证调用变量时能从当前层级往上能找到即可
@{selector} {
@{attr}: @value;
@value: red;
}
@attr: color;
@selector: p;
//虽然定义在下
//但能从调用处往上寻找时能搜查到此层级
另外这种搜查机制也对于同名变量来说符合就近原则
p {
@v: #123;
color: @v;
@v: #456;
//结果为#456
//它会优先搜查一遍
//搜查后#456当然覆盖了#123
}
@v: #789;
//由于调用那一层已经搜查到了
//因此无需向上搜查此层
二、属性值运算
赋值
上面有讲过便不再赘述
@a: 10;
@b: @a;
空格附加
比如CSS中margin多个属性值来说是通过空格来间隔开的,LESS提供这样一个机制去实现多个属性值空格相加
通过+_
符号以空格形式附加属性值
@v1: 10px;
@v2: 20px;
@v3: 30px;
@v4: 40px;
.div1{
/*已忽略其他必要属性*/
margin+_: @v1;
margin+_: @v2;
margin+_: @v3;
margin+_: @v4;
}
.div2{
margin: @v1 @v2 @v3 @v4;
//虽然也能通过这种方式附加
//这与后面的函数相关联
//比如设定一个函数附加属性值
//这样的机制无法实现而+_可以
}
逗号附加
还有一类属性值必须要通过逗号隔开,LESS是通过+
符号以逗号形式附加属性值
这里不作演示了
简单运算
对于Less而言它可以进行一些简单的运算,当然在Less内置函数中还内置大量数学函数可以实现非常复杂的运算
@size: 10;
@o1: @size + 5;
@o2: @size - 5;
@o3: @size * 5;
div {
d1: @o1;
d2: @o2;
d3: @o3;
}
三、嵌套(Nesting)
嵌套
嵌套是非常常用的工具,可以使大量CSS难以看清楚的结构,在Less中变得显而易见
father {
display: flow-root;
.first,.second {
width: 400px;
height: 200px;
}
.first {
margin-bottom: 100px;
background: purple;
}
.second {
margin-top: 200px;
background: green;
}
}
//比如这里显而易见的,father中套了first、second
//而CSS处理的话只会分开,当数量足够多时便很难分清结构了
引用父元素
嵌套虽然实现了父类→子类的,但无法实现子类→父类,&提供了从子类→父类的功能
这一般用于类、复杂运算、属性值选择器或是伪类,如下例只需要&即可实现不同伪类的情况,同样其结构也更加清晰
a {
font-size: 20px;
background: pink;
&:link {
color: red;
}
&:visited {
color: green;
}
&:active {
color: hotpink;
}
&:hover {
color: blue;
}
}
所谓引用是真的完全引用,不会有太大的语法限制
也会有这种形式的LESS代码
.area {
&-1 {}
&-2 {}
//类
& &[data-v1="3"]:hover{}
.father &{}
//假设.father盒子嵌套.area盒子
//那么可以实现这种嵌套的样式
//复杂运算
}
//通过这种方式可以很好地集成代码
你可能会担心还会生成一个.area的父类,但实际上LESS会进行优化,只要你的选择里没有任何样式那么它就不会生成此类。.area下面全都是选择器,并不是具体的样式,因此它不会生成.area这一个父类,可以放心大胆地使用这种代码
引用父元素的组合
上面阐述了引用父元素下其子元素能够如何如何之类的,但是其父元素也是可以参与运算的,这样会导致更加灵活的嵌套,但目前我个人没找到这种实际应用的场景
.a,.b > .c{
& & {}
}
因为CSS除了组合运算以外不管是伪类也好属性选择器也好,它本质上都只是一个选择器,但组合选择器是多个。
核心在于组合运算,上面例子仅仅是组合了.a和.b > .c两个选择器,使用& &{}会是什么?
LESS会把每一个&尝试组合中的所有选择器
结果会是
.a .a,
.a .b > .c,
.b > .c .a,
.b > .c .b > .c {
/*某个样式*/
}
这里简单用数学计算下,假设LESS代码里定义选择器时有n个&符号,而父类组合的有m个选择器,那么其组合后总共会去组合个选择器
四、混合(Mixins)
函数
这里博主统一称为函数,一个样式规则集可以当作函数。函数内部可以写好一个样式模板,某个属性需要时调用即可
但是需要注意函数的命名必须是类选择器或是id选择器的命名
.a , #b {
//既可以当作某个样式渲染(如果HTML中满足的话)
//也可以当作函数来调用
color: red;
font-size: 19px;
}
.father {
#b();
}
由于版本原因,调用的时候()是可选的,在未来版本可能会被删除
.a , #b {
color: red;
font-size: 19px;
}
.father {
.a;
//不用()也能生效
}
参数
上面的语法也会当作样式来渲染,但有时候可能就想当作函数,这时候只需要在函数后加上()即可
.c() {
//不会生成.c的CSS代码
color: red;
&:link {
color: red;
}
&:visited {
color: green;
}
&:active {
color: hotpink;
}
&:hover {
color: blue;
}
}
a {
.c;//此时&引用是a
}
此外可以设置形参来传递实现更复杂的操作
.color(@color){
color: @color;
}
.fontsize(@size: 16px){
//可以设置默认值
font-size: @size;
}
p {
.color(black);
//未设置默认值必须填写参数
.fontsize();
}
在写默认值有时并不止一个属性值
如果多个属性值是要用,
分隔的,此时可以用;
分隔参数
如果多个属性值是用空格分隔的,可以用,
也可以用;
分隔参数
.a(@border:3px solid red ; @margin:0 auto){
//用;分隔参数
border: @border;
margin: @margin;
}
div {
.a;
}
调用参数时可以指定形参名,这时调用无需注意顺序
.a(@border:3px solid red;@margin:0 auto){
border: @border;
margin: @margin;
}
div{
.a(@margin:10%);
}
函数的嵌套
由于嵌套语法的存在,函数也是可以嵌套的
LESS提供了三种等价性的调用方式
分别是.father > .son,.father .son和.father.son
这三种形式没有任何区别,它会调用所有下一级子函数的样式
.a(){
color:blue;
font-size: 18px;
.b(){
padding: 0;
color:red;
.b(){
margin: 0;
}
}
.b(){
background: black;
color:blue;
//LESS输出并不会去覆盖样式
//因此结果里会有两个color
}
}
.div1 {
.a.b;
}
.div2 {
.a > .b .b();
}
调用的函数只会在这一层而不会出现其父类或是子类的函数,若要使用子类的函数必须去调用才行
守卫(Guard)
在LESS中when的保护条件称为是Guard,其中只有满足when条件才可执行,不满足不会被执行
.a() when(true){
color: red;
}
p {
.a;
}
.b() when (@mode = 1){
color: blue;
}
p {
@mode: 2;
.b;
//@mode为2不满足
//因此会拒绝.b()函数调用
}
在1.5以后守卫机制不仅可以适用于函数还可以适用于选择器上
@my-option: true;
& when (@my-option = true) {
//备注:若不存在&则不会有父元素
//但可以用不存在的元素专门用作条件语句
button {
color: white;
}
a {
color: blue;
}
}
@arguments
@arguments可以将所有参数同时传递
.pos(@top: 0; @right: 0; @bottom: 0; @left: 0) {
margin: @arguments;
padding: @arguments;
//同时传递了@top @right @bottom @left
//且参数之间是空格附加的
}
div {
.pos(50px,30px,50px,20px);
}
@rest以及不定参数
用...可以表示不定参数,@rest可以指定剩余的可变参数
但CSS的属性值绝大部分都是有限个,因此应用场景可能不多
.minin()){}//无参
.minin(@rest...){}//任意个参数
.minin(@a){}//无参或一个参数
.minin(@a;@rest...){}//任意个参数
.minin(@a: 1;@rest...){}//至少一个参数
模式匹配
LESS的函数是只要满足就会实现,因此可以设定一个常量作为形参
当满足该常量时便会执行,否则不会执行,可以作为不同情况的函数
.mixin(dark; @color) {
color: darken(@color, 10%);
}
.mixin(light; @color) {
color: lighten(@color, 10%);
}
div {
.mixin(light, #888);
.mixin(dark,#aaa);
//执行drak的.mixin函数
}
实现分支结构
LESS中是通过保护条件来实现分支语句的,如下面实现采用更大宽度的代码
.max(@a; @b) when (@a > @b) { width: @a }
.max(@a; @b) when (@a < @b) { width: @b }
此外条件之间也可以使用and、or、not这三类逻辑运算符
对于函数的返回值博主认为应用场景不多故此忽略,详细可在官网中查看器语法
至于循环结构博主认为只需要在第六节提到的each方法即可实现,无需本身的循环结构
实现哈希表(v3.5.0)
在3.5.0的版本中变量可以去存储函数,基于这个机制可以实现哈希表
#Font(){
//定义#Font实例内置size、color数据
.size(){
style1: 12px;
style2: 15px;
style3: 18px;
}
.color(){
style1: black;
style2: white;
style3: grey;
}
}
p{
@f-c: #Font.color();
color: @f-c[style1];
font-size: #Font.size()[style3];
//可以直接通过函数去索引相当于哈希表
}
选择器、属性名作为参数
我之前用less确确实实有这么一个需求,需要针对不同类名某些相同属性设定不同的属性值,那么可以如下实现
.f(@selector,@value){
//@selector作为类选择器参数
.@{selector} {
font-size: @value;
}
}
.f(m1,12px);
.f(m2,14px);
.f(m3,16px);
此时可以将选择器作为一个形参来设置属性值,属性名同理这里不再赘述
函数作为参数
函数本身也是可以作为形参对象的,这在封装某些代码时会非常有用
.media(@rules1,@rules2) {
@media screen and (max-width: 799px) {
@rules1()
}
@media screen and (min-width: 800px) {
@rules2();
}
}
.f(){
font-size: 18px;
}
.g(){
font-size: 24px;
}
* {
.media(.f(),.g());
//备注:必须加()否则出错
}
五、扩展(Extend)
Less中有一个特殊的伪类——extend,它用于实现组合运算
因为有时仅仅是嵌套,混合并不能完全满足开发需求,扩展适用于选择器组合运算时的某些相同样式
extend伪类
下例将会先生成nav选择器,再生成nav, .inline选择器
nav {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
extend内同样可以有多个选择器的组合形式
.div1:extend(.f, .g) {}
//extend参数组合等价于下面两行语句
.div1:extend(.f) {}
.div1:extend(.g) {}
//LESS允许多个extend但效果仍然是组合
//下面的代码与上面的是等价的
.div1 :extend(.f) :extend(.g) {}
//备注:extend允许与选择器之间存在空格
同样地除了内部参数的组合还可以有父选择器的组合
pre:hover, .some-class {
&:extend(div pre);
}
//等价于如下代码
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
extend伪类可能会与其他伪类相互结合,但LESS的extend伪类必须位于最后,否则报错
pre:hover:extend(div pre).nth-child(odd) {}
//报错,extend伪类必须位于最后
精确匹配
extend内的选择器是精确匹配的,附加任何运算形式都不会计算在内
*.class {
color: blue;
}
.noStar:extend(.class) {
//不存在.class选择器
//不会有任何组合效果
color: red;
}
all选项
扩展虽然是精确匹配的,但all参数可以解除这种精确性
使用all参数匹配会改成匹配有关参数的所有选择器,并且会进行相同的运算
.div:extend(.other all) {
//组合有关.other的所有选择器
//且会进行相同运算的组合
}
.other {
//会去精确匹配
color: blue;
}
*.other {
//附上了运算
//得到的组合会是*.div, *.other
margin: 0 auto;
}
.other > .e {
//同理组合是.div > .e, .other > .e
padding: 0;
}
.father{
//同理组合是.father .div,.father .other
border-style: dashed;
.other {
overflow: hidden;
}
}
.other {
//同理组合是.div .sub,.other .sub
clear: left;
.sub {
display: flow-root;
}
}
缺陷
目前extend组合语法并不支持在参数内使用变量,因为语法角度来说是有可能会用到extend内为变量去动态地组合
但是外部的选择器是可以使用变量替代的
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
六、其他
@import声明(1.4.0)
与CSS不同的是Less的@import可以随意在任意地方声明
Less可以去调用其他样式文件,调用后其文档原本全局变量的作用域会改成当前文档
@pref: "../lessheader";
p {
font-size: @size2;
}
@import "@{pref}/header1.less"
/*假设@size2在header1.less中
这里提供了一种类似于头文件的声明方式
可以去管理Less的变量、函数
*/
还有其他一部分内容,但属于提高less的可扩展性,这里就不做过多介绍了
数学函数
备注:CSS有单位一说,但大部分数学函数转换后依然是原本单位
函数 | 说明 |
---|---|
pi() | 返回圆周率π |
abs(x) | x取绝对值 |
ceil(x) | 对x上取整 |
floor(x) | 对x下取整 |
percentage(x) | 将x转成百分数,如0.15转成15% |
round(x,decimal) | 对x第decimal位四舍五入 decimal可省略默认为0即整数四舍五入 如round(1.8877,2)会返回1.89 |
mod(a, b) | 返回a%b |
sqrt(x) | x取根号 |
pow(base, exp) | 返回base的exp方 |
sin(x),cos(x),tan(x) | 三角函数,详细见备注 |
asin(x),acos(x),acot(x) | 反三角函数,详细见备注 |
min(v1,...),max(v1,...) | 至少输入1个参数,返回最小/大值 |
备注:LESS对三角函数支持三类单位,分别是弧度制、角度制、百分度制,但返回值统一是弧度制
sin(2);//弧度制
cos(60deg);//角度制
tan(100grad);//百分度制
布尔值
Less以函数形式支持boolean数据类型
创建条件如下
@flag: boolean(/*条件*/@a > 5);
@a: 10;
if函数
虽然有guard机制实现分支,但也以函数形式提供了分支语句
格式为【if(条件,true时执行语句,false时执行语句)】
其中可以忽略最后的false时执行的语句
若要实现if-else的结构需要在false处再嵌套if语句
@bg: black;
@bg-light: boolean(luma(@bg) > 50%);
div {
background: @bg;
color: if(@bg-light, black, white);
}
字符串常用函数
函数 | 说明 |
---|---|
e(str) | 删除str的分号 如具体处理时采用字符串 但调用却不是字符串那么可以使用此方法 |
%(str,arg,...) | 格式化字符串,详细见备注 |
备注:可以使用%函数来格式化字符串,其中占位符有分大小写,其中小写会保持特殊字符的原样,而大写会将特殊字符转成UTF-8编码形式,如空格会转成%20
,/会转成%2
由于使用了%表示占位符,若要表示%本身需要写成%%
占位符 | 说明 |
---|---|
%a,%A,%d,%D | 与其他语言不同 它可以被任何类型替代而不是专指某类数据类型 |
%s,%S | 上一方式在表达字符串时存在问题 它会将表述字符串的引号 使用这一类占位符可以忽略字符串的引号 |
format-a-d-upper: %('repetitions: %A file: %d', 1 + 2, "directory/file.less");
//存在问题,由于不是%s会带来引号
数组
Less支持一个变量去定义数组,在某些情况可能有较好的效果
比如设计网站后将所有会用到的颜色集成一个数组
@Color: "white" "grey" "green";
//用逗号分隔或空格分隔即可定义数组
//但需要统一分隔符,除非属性值的表述需要分隔符
数组相关函数 | 说明 | 版本说明 |
---|---|---|
length(arr) | 返回数组元素个数 | |
extract(arr, index) | 索引,返回arr第index个元素 备注:下标从1开始 |
|
range(start,end,step) | 详细见下节内容 | v3.9.0 |
each(arr, rules) | 详细见下节内容 | v3.7.0 |
@Color: "white" "grey" "green";
p {
color: extract(@Color,2);
//设置为灰色,但这里存在些问题
}
高版本功能:实现循环结构(v3.9.0)
数组新方法特别好用,蓝桥杯web比赛的less只支持到2.x的版本可惜了
range函数用于生成数组,each用做循环
range(2,5,2);//返回数组元素2 4
range(3);
//也可以省略初值和步长,默认为1
//返回数组1 2 3
each函数用来迭代
each(@selector, {
@{selector}{
margin: 0 auto;
}
});
//第一个参数为数组
//第二个参数为函数可以匿名定义
解析获取属性值
Less提供了一类函数可以通过某些值来获取相应属性值,比如只要知道图像的url就可以获取其大小
函数 | 说明 | 版本说明 |
---|---|---|
color(str) | 字符串转成颜色值 | |
image-size(str) | 根据字符串表述的url返回相应文件的大小 备注:同时返回宽度和高度可以用数组来接收 |
2.2.0 |
image-widtht(str) | 同上但只返回宽度 | 2.2.0 |
image-height(str) | 同上但只返回高度 | 2.2.0 |
unit(number,unit) | ①若省略unit作用是返回其不带单位的数字本身,在运算上不会出现混乱,如unit(1000ms)返回为1000 ②不省略unit则会去设置单位,不管原本number有没有单位都会替换,如unit(10px,cm)返回10cm |
|
get-unit(number) | 返回number的单位,若无单位不会返回任何内容 该函数可以结合unit进行较灵活的单位转换 |
|
convert(number,unit) | 将number的单位及数值进行等价替换 unit纯粹是改变单位,但convert还会换算数值 convert限定了必须在某一组单位进行转换否则不会产生任何效果 ①长度:m, cm, mm, in, pt, pc ②s, ms ③角度:rad, deg, grad, turn |
convert(9s, "ms");
//在时间组内等价替换成9000ms
@Color: "white" "grey" "green";
p {
color: color(extract(@Color,2));
//直接从数组获取字符串但它并不是颜色值
//通过color函数转成可用的颜色值
}
判定类型
Less提供一组函数用于判定不同的数据类型
函数 | 说明 |
---|---|
isnumber(x) | 判定是否为数值 |
isstring(x) | 判定是否为字符串 |
iscolor(x) | 判定是否为颜色值 |
isurl(x) | 判断是否为url |
ispixel(x) | 判断其单位是否为px |
isem(x) | 判断其单位是否为em |
ispercentage(x) | 判断其单位是否为% |
isunit(x,unit) | 判断其单位是否为unit |
isruleset(x) | 判断是否为规则集 由于变量可以表述任何内容 导致有时并不能直接看出一个变量代表着什么 |
备注:严格来说上面的函数准确名字叫做规则集,函数是指带返回值的
但这里博主自作主张地称其为函数
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析