前言
以前都是用 css,自从看到有人使用了 less 之后,我就感觉,这东西用着真舒服呀,就赶紧学习了一下,尤其是 选择器中变量的实用,选择器的嵌套(父子选择器)
,真的别提有多方便实用了
看了之后,你还感觉不行不好用,那么熄熄火,咱们不用就是了,对吧😂
话不多说,直接开始讲解
less前置 -- css 变量、特殊符号介
css
中变量
和特殊符号
想必大家也都接触过,这里也简单介绍下,避免部分没有接触过的读者到 less
这部分时懵逼
css 变量
ps
:只可以在括号内声明变量,限制比较多,且声明位置和使用看着有点怪
// 两边名前加入 --变量名
// 使用 var(--变量名) 使用变量
.test-text {
//有效,且变量不允许声明到外面
--font-z: 100px;
font-size: var(--font-z);
//无效,不能拼接,只能设置最终结果
--font-z: 100;
font-size: var(--font-z)px;
}
css 特殊符号
主要介绍:逗号(,)
、空格
、>
、+
、~
、*
逗号(,)
: 可以让多个选择器拥有相同属性
,此外,同名选择器
会同时应用该名字所有属性
(这两个功能一起应用,可以理解为选择器的多态)
空格
、>
、+
、~
、*
等: 可以给指定节点(当前节点、子节点)
设置属性
/* 逗号、空格、>、+、~、* */
/* ,: 逗号隔开的选择器,同时拥有括号内声明的属性 */
/* 设置选择器的,需要通过 className 设置到对应标签中 */
.test-text, .test-text1, .test-text2 {
color: blue;
}
/* 应用于当前节点,此时他会比另外两个属性多出一个font-size属性,同名属性属性最终会被合并 */
.test-text {
font-size: 40px;
}
/* 下面的应用于所有子节点(标签选择器:div、类别选择器:.test-text) */
/* 空格: 容器内,所有 p 节点 */
.test-text p {
font-size: 20px;
}
/* 空格: 容器内,所有类别选择器为 test-text1 的 */
.test-text .test-text1 {
font-size: 20px;
}
/* 后面案例均以标签选择器,即节点为例 */
/* >: 容器内,指定第一层直接子节点 p,不会应用于孙节点以及以后节点*/
.test-text > p {
font-size: 60px;
}
/* +: 容器内的所有子节点中, 符合 p 后面紧相邻兄弟节点(下一个节点)为 div 时生效,有一组生效一组 */
.test-text p + div {
color: red;
}
/* ~: 容器内的所有子节点中,符合 p 的同级节点中为 div 的兄弟节点,都生效 */
.test-text div ~ p {
color: green;
}
/* * 应用到容器内,所有子元素 */
.test-text * {
background-color: yellow;
}
顺便补充一下并列选择器、属性选择器
/* 并列选择器 连接到一起表示多个选择器作为样式筛选条件 */
div.test-text {
font-size:30;
}
[id="name"] {
font-size: 30;
}
他们是选择器的权值和顺序,如果一行css多个重复选择器,则实际根据权值相加表示优先级,优先级一致,后者代替前者
!important > style > id选择器 > class选择器 | 属性 | 伪类 > 标签选择器 | 伪元素 > 通配符选择器
ps补充
:如果有些环境 less 也不行,可以试试 scss,scss 的 这篇 介绍就挺好
less 环境配置
假设使用的是 create-react-app 模版,安装一下 craco
相关环境(有些自行配置webpack的就不需要了,毕竟里面loader配置很容易)
yarn add @craco/craco
yarn add craco-less
修改 package.json
中的 script
标签
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
},
package.js
同级目录下加入 craco.config.js
-- craco配置说明
//引入 craco-less插件
const CracoLessPlugin = require('craco-less');
module.exports = {
typescript: {
enableTypeChecking: true /* (default value) */,
},
plugins: [
{
plugin: CracoLessPlugin,
// options: {
// lessLoaderOptions: {
// lessOptions: {
// modifyVars: { '@primary-color': '#1DA57A' },
// javascriptEnabled: true,
// },
// },
// },
},
],
};
less 语法
从上面的 css 案例也可以看出来,就单纯一个变量就用着很不方便,还有嵌套方式写css属性的问题(报警告),还有less后面支持的复用css,好像也没看到,少了很多便利性,嵌套可能也没有less支持的那么好,可以的话,优先使用less,会体会到他的便利
变量声明
通过 @ + 变量名
的方式来声明变量,如下所示
@theme-color: blue;
@normal-text: 14px;
变量的使用
通过@{变量名}
、 @变量名
两种方式来使用, @变量名
用于值, @{变量名}
主要用于选择器、属性、字符串拼接
//在外部声明一些可能会多次使用的变量
@text-color: #333;
@line-name: width;
@line-value: 100px;
@mine: './images/mine/';
@home: './images/home/';
@selector-name: app;
//如果给选择器命名需要@{}
.@{selector-name} {
display: flex;
flex-direction: column;
}
.text1 {
color: @text-color; //值类型,直接使用 @ + 变量名
font-size: 30px;
}
.text2 {
color: @text-color * 3; //值类型可以参与运算,不仅可以计算颜色 px也可以参与运算
font-size: 20px;
}
.red-block {
@{line-name}: @line-value; //属性也需要@{},值只需要@
height: @line-value;
background-color: red;
}
.img-logo {
width: 100px;
height: 100px;
background-image: url("@{mine}logo192.png"); //拼接字符串你需要 @{}
background-repeat: no-repeat;
background-size: cover;
}
附加:全局选择器和变量
可以单独编写一个 global.less
文件,声明比较常用的一些全局变量、选择器,配合使用,可以说更为方便
@theme-color: blue;
@theme-bkg: blue;
.theme-color {
color: @theme-color;
}
.theme-bkg {
background-color: @theme-color;
}
父子选择器
从下面可以看到,直接镶嵌到里面就可以了,父子关系一目了然,需要注意的是特殊符号,默认为空格,需要用到特殊符号的加上即可
.content1 {
display: flex;
flex-direction: row;
//会自动生效到子选择器
.text {
color: red();
font-size: 30px;
}
//应用到直属子节点,其他一样 > + , ~ 等均生效
> .img-logo {
width: 100px;
height: 100px;
background-image: url("../images/logo192.png");
background-repeat: no-repeat;
background-size: cover;
}
}
同时使用 &
来实现名称替换,如下所示,实际能应用得更多
.content2 {
display: flex;
flex-direction: row;
//下面的 & 均会被替换为父类名称 div
div {
width: 20px;
height: 20px;
background-color: red;
//&会自动替换外层名称,下面相当于 div:hover
//如果是类选择器存在前缀的也可以
&:hover {
background-color: green;
}
// 相当于 div-subdiv,字符拼接了,&必须在前,因此比较适合标签选择器
&-subdiv {
background-color: green;
}
}
}
样式继承 extend
如下所示,使用 extend
继承实体样式,看起来更像类的继承了
.center {
justify-content: center;
align-items: center;
}
//可以继承实体样式,共同拥有,却不重复生成
.content3:extend(.center) {
display: flex;
width: 80px;
height: 40px;
background-color: greenyellow;
div {
width: 20px;
height: 20px;
background-color: red;
border-radius: 50%;
}
}
隐藏样式(虚拟节点)
虚拟节点是一个隐藏样式,调用时会被默认展开到指定类,实际编译的 css 类并不会存在
//虚拟节点实际不存在,调用时,类似宏定义,展开后使用内容更换外部调用出,因此会重复
.center() {
justify-content: center;
align-items: center;
}
.content4 {
display: flex;
width: 100px;
height: 40px;
background-color: yellow;
// .center();
.center; //这两种都可以,推荐这个,且实体节点也可以这么展开
div {
width: 20px;
height: 20px;
background-color: red;
border-radius: 50%;
}
}
!important
在继承展开虚拟节点的时候,可以使用 !important
,其可以让继承的节点所有属性都加上 !important
,这对于修改一些三方组件时,别提有多方便了
.mixin_content5() {
background-color: red;
width: 100px;
height: 10px;
.height() {
height: 60px;
}
.gray() {
background-color: green;
}
}
.content5 {
/*可以使继承到的所有属性都添加!important*/
.mixin_content5 !important;
//符号类似
.mixin_content5>.height; //应用内部的子样式,由于前面 import 所以不生效
.mixin_content5>.gray !important; //!important更新属性生效了
}
模式匹配
通过固定参数,来选择展开哪一个选择器,如下所示
.mixin (dark, @color) {
background-color: #333;
}
.mixin (light, @color) {
background-color: #fff;
}
div {
.mixin(dark, red)
}
参数混合
我们设计虚拟节点的时候也可以设置参数,继承调用时,通过传递指定参数,调用更简单,开发代码更少了,更好理解了
/*可以设定参数,也可以同时设置默认值*/
//下面的参数实际上就是局部变量,可通过修改局部变量来更新内容
.transition(@property: all; @duration: 1s; @function: linear; @delay: 0s; ) {
-webkit-transition: @property @duration @function @delay;
-moz-transition: @property @duration @function @delay;
-ms-transition: @property @duration @function @delay;
-o-transition: @property @duration @function @delay;
transition: @property @duration @function @delay;
}
/*等同于上式,Less中也有arguments*/
.transition(@property: all; @duration: 1s; @function: linear; @delay: 0s; ) {
-webkit-transition: @arguments;
-moz-transition: @arguments;
-ms-transition: @arguments;
-o-transition: @arguments;
transition: @arguments;
}
.content6 {
width: 60px;
height: 60px;
background-color: yellow;
.transition(@property: width; @duration: 2s; )
}
兼并 merge
兼并多个相同属性(+
代表以逗号,
分隔,+_
代表多个之前以空格
分隔)
// 兼并多个相同属性(+代表以逗号分隔,+_代表多个之前以空格分隔)
.shadow() {
box-shadow+: inset 0 0 10px #555; //内阴影
}
.scale(@num) {
transform+_: scale(@num); //大小变换
}
.content8 {
width: 200px;
height: 60px;
margin-top: 10px;
border-radius: 20px;
.shadow;
box-shadow+: 0 10px 20px #333; //外阴影
transform+_: translateX(60px); //位移变换
.scale(1.2);
}
方便理解,这里面翻译一下
// box-shadow: inset 0 0 10px #555, 0 0 20px black;
// transform: translateX(100px) scale(2);
条件语句 when
when
有点像if
了,使用也很简洁,如下所示
ps
:如果想展开多个,可以通过,参数混合 + 递归(调用自身)
等方式展开,这样就能一次生成多条css数据了
//when条件语句,也可以在里面调用自身,形成递归,通过变量控制,一次性生成多条属性
.alpha(@a) when (@a >=0.5) {
background-color: #eee;
}
.alpha(@a) when (@a < 0.5) {
background-color: #333;
}
.content7 {
width: 200px;
height: 60px;
background-color: red;
.alpha(0.3);
}
其他的个人感觉并不是很好
最后
其他 less
用的非常不多的就不多介绍了,目前只介绍一些比较常用的,或者可能会用到的,但就这样就能明显感觉到收获很多,可以自行运行环境尝试哈
ps
:至少看到别人的 less
代码,立马就知道咋回事了,而不是半懵逼或者猜测状态,另外,想看实际编译后的css
文件,可以build
之后搜索查看哈