官网: Less 快速入门 | Less.js 中文文档 - Less 中文网
LESS很多地方可以比CSS简写很多
安装
npm install -g less
核心优势:变量、嵌套、混合、运算功能让CSS更容易维护,比原生CSS更加简洁高效
1. 变量(Variables)
@primary-color: #428bca;
@padding: 15px;
.header {
background: @primary-color;
padding: @padding;
}
2. 嵌套(Nesting)
.nav {
ul {
margin: 0;
li {
display: inline-block;
a {
color: #333;
}
}
}
}
3. 混合(Mixins)
.border-radius(@radius: 5px) {
border-radius: @radius;
}
.button {
.border-radius();
&.large {
.border-radius(10px);
}
}
4. 运算(Operations)
@base-width: 100px;
@padding: 20px;
.container {
width: @base-width + @padding * 2;
}
内置函数重点
简单的示例之后是按照使用频率提取出来重点
数学函数(Math Functions)
@number: 3.14;
div {
width: ceil(@number); // 4
height: floor(@number); // 3
line-height: round(@number); // 3
margin: percentage(0.5); // 50%
}
数学函数 | percentage() |
⭐⭐⭐⭐⭐ | 小数转百分比 | width: percentage(0.5); → 50% |
round() |
⭐⭐⭐⭐ | 四舍五入 | border-radius: round(3.6); → 4px |
|
ceil()/floor() |
⭐⭐⭐ | 向上/向下取整 | height: ceil(3.2); → 4px width: floor(3.8); → 3px |
|
min()/max() |
⭐⭐⭐⭐ | 取最小/最大值 | width: max(100px, 50%); |
|
sqrt() |
⭐⭐ | 计算平方根 | width: sqrt(16); → 4px |
颜色函数(Color Functions)
@color: #428bca;
a {
color: lighten(@color, 20%);
&:hover {
color: darken(@color, 10%);
}
}
颜色函数 | lighten()/darken() |
⭐⭐⭐⭐⭐ | 颜色增亮/变暗 | background: lighten(#428bca, 20%); hover: darken(#428bca, 10%); |
fade()/fadein()/fadeout() |
⭐⭐⭐⭐ | 透明度控制 | color: fade(#ff0000, 50%); → rgba(255,0,0,0.5) |
|
mix() |
⭐⭐⭐⭐ | 颜色混合 | background: mix(red, blue, 50%); → #800080 |
|
saturate()/desaturate() |
⭐⭐⭐ | 调整饱和度 | color: saturate(#55aaff, 20%); |
|
grayscale() |
⭐⭐ | 颜色转灰度 | filter: grayscale(100%); |
|
contrast() |
⭐⭐⭐ | 自动生成对比色 | color: contrast(#333); → white |
|
rgba() |
⭐⭐⭐⭐⭐ | 转换颜色格式 | background: rgba(#ff0000, 0.5); → rgba(255,0,0,0.5) |
字符串函数(String Functions)
@url: "image.png?size=large";
div {
background: escape(@url); // 编码URL
}
字符串函数 | escape() |
⭐⭐⭐ | URL编码 | background: url(escape("image name.png")); |
% format() |
⭐⭐ | 字符串格式化 | content: %("Hello %s", "world"); → "Hello world" |
|
replace() |
⭐ | 字符串替换 | content: replace("Hello IE", "IE", "Edge"); |
列表函数(List Functions)
@list: "Arial", "Helvetica", sans-serif;
body {
font-family: extract(@list, 2); // Helvetica
}
css1. 列表函数实战 - 生成间距系统
// 定义间距列表
@spacings: 4px, 8px, 12px, 16px, 24px;
// 自动生成工具类
each(@spacings, {
.m-@{index} {
margin: @value;
}
.p-@{index} {
padding: @value;
}
});
CSS运行逻辑:
.m-1 { margin: 4px; }
.p-1 { padding: 4px; }
.m-2 { margin: 8px; }
/* 其他省略... */
列表函数 | length() |
⭐⭐⭐ | 获取列表长度 | less<br>@colors: red, green, blue;<br>count: length(@colors); // 输出 3<br> |
extract() |
⭐⭐⭐⭐ | 提取列表指定位置元素 | less<br>@fonts: Arial, Helvetica, sans-serif;<br>font: extract(@fonts, 2); // Helvetica<br> |
|
range() |
⭐⭐ | 生成数字序列 | less<br>@sizes: range(4px, 16px, 4); // 生成 4px, 8px, 12px, 16px<br> |
类型检查函数(Type Functions)
@value: #fff;
div {
@if(iscolor(@value)) {
color: @value;
}
}
类型检查 | iscolor() |
⭐⭐⭐⭐ | 检查是否为颜色值 | less<br>@if(iscolor(#fff)) { color: #fff; }<br> |
isnumber() |
⭐⭐⭐ | 检查是否为数字 | less<br>@if(isnumber(10px)) { width: 10px; }<br> |
|
isunit() |
⭐⭐ | 检查单位 | less<br>@if(isunit(10px, px)) { height: 10px; }<br> |
逻辑控制(Conditionals)
@theme: dark;
.header {
@if (@theme = dark) {
background: #333;
color: #fff;
} @else {
background: #fff;
color: #333;
}
}
逻辑控制 | @if |
⭐⭐⭐⭐⭐ | 条件判断 | less<br>@theme: dark;<br>.box {<br> @if (@theme = dark) {<br> background: #000;<br> }<br>}<br> |
when |
⭐⭐⭐⭐ | 混合条件 | less<br>.text-style(@size) when (@size > 12px) {<br> font-weight: bold;<br>}<br> |
类型检查+逻辑控制 - 安全混合
// 安全的颜色混合函数
.safe-mix(@c1, @c2, @weight) when (iscolor(@c1)) and (iscolor(@c2)) {
color: mix(@c1, @c2, @weight);
}
// 使用示例
.error-text {
.safe-mix(red, "notacolor", 50%); // 不会生效(因为第二个参数不是颜色)
}
循环(Loops)
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i <= @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
循环 | each() |
⭐⭐⭐⭐ | 遍历列表 | less<br>@colors: red, green, blue;<br>.each-color() {<br> each(@colors, {<br> .color-@{value} {<br> color: @value;<br> }<br> });<br>}<br> |
.for 循环 |
⭐⭐⭐ | 数字循环 | less<br>.generate-columns(4);<br>.generate-columns(@n, @i: 1) when (@i <= @n) {<br> .col-@{i} { width: (@i * 100% / @n); }<br> .generate-columns(@n, (@i + 1));<br>}<br> |
实战
这是之前写的一段CSS的代码,
.container{
width:90%;
max-width:1100px;
margin:auto;
}
.main-nav{
display:flex;
align-items: center;
justify-content: space-between;
height: 60px;
padding: 10px;
font-size:13px;
}
.main-nav .logo{
width:110px;
}
.main-nav ul{
list-style-type: none; /* 去除无序列表的项目符号 */
display:flex;
}
.main-nav ul li{
padding: 0 10px;
}
.main-nav ul li a{
padding-bottom: 2px;
text-decoration: none;
color: #333;
}
.main-nav ul li a:hover{
border-bottom: 2px solid #000000;
}
.main-nav ul.main-menu{
flex:1;
margin-left: 20px;
}
.menu-btn{
cursor:pointer;
position:absolute;
top:10px;
right:30px;
z-index:2;
display:none;
}
.btn{
cursor:pointer;
display:inline-block;
border:0;
font-weight:bold;
padding: 10px 20px;
background: #262626;
color:#fff;
font-size:15px;
text-decoration: none;;
}
.btn:hover{
opacity:0.9;
}
.dark{
color:#fff;
}
.dark .btn{
background: #f4f4f4;
color:#333;;
}
.showcase{
width:100%;
height:400px;
background:url('https://i.ibb.co/zGSDGCL/slide1.png') no-repeat center center/cover;
display:flex;
flex-direction:column;
justify-content:flex-end;
align-items:center;
text-align:center;
padding-bottom: 50px;
margin-bottom:20px;
}
.showcase h2, .showcase p{
margin-bottom:10px;
}
.showcase .btn{
margin-bottom:10px;
}
.home-cards{
display:flex;
grid-template-columns: repeat(4,1fr);
grid-gap:10px;
margin-bottom: 40px;
}
.home-cards img{
width:100%;
height: auto; /* 保持图片的宽高比 */
object-fit: cover; /* 使图片完全覆盖容器,可能会裁剪图片 */
margin-bottom:20px;
}
.home-cards h3{
margin-bottom:5px;
}
.home-cards a{
display:inline-block;
padding-top:10px;
font-weight:bold;
color:#0067b8;
text-transform:uppercase;
}
.home-cards a:hover{
margin-left:10px;
}
.xbox{
width:100%;
height: 350px;
background:url('https://i.ibb.co/tBJGPD9/xbox.png') no-repeat center center/cover;
margin-bottom:20px;
display:flex;
flex-direction:column;
justify-content:center;
}
.xbox .content{
width:40%;
padding:50px 0 0 30px;
}
.xbox p,carbon p{
margin:10px 0 20px
}
.carbon{
width:100%;
height:350px;
background:url('https://i.ibb.co/zVqhWn2/card5.png') no-repeat center center/cover;
margin-bottom:20px;
display:flex;
}
.carbon .content{
width:40%;
margin-left:20px;
margin-top:20px;
}
.carbon .btn{
margin-top:30px;
}
.links .links-inner {
background: #f4f4f4;
display:grid;
grid-template-columns: repeat(5, 1fr);
}
@media(max-width: 500px) {
.home-cards {
grid-template-columns: 1fr;
}
.links .links-inner {
grid-template-columns: 1fr;
}
.links .links-inner ul {
margin-bottom: 20px;
}
}
用less优化
@container-width: 90%;
@container-max-width: 1100px;
@nav-height: 60px;
@nav-padding: 10px;
@nav-font-size: 13px;
@logo-width: 110px;
@menu-margin-left: 20px;
@btn-padding: 10px 20px;
@btn-font-size: 15px;
@showcase-height: 400px;
@xbox-height: 350px;
@carbon-height: 350px;
@grid-gap: 10px;
@hover-transition: all 0.3s ease;
.flex-center(){
display:flex;
align-items:center;
justify-content:center;
}
.flex-between() {
display: flex;
align-items: center;
justify-content: space-between;
}
.background-cover() {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
// 基础样式
.container {
width: @container-width;
max-width: @container-max-width;
margin: auto;
}
// 导航栏样式
.main-nav {
.flex-between();
height: @nav-height;
padding: @nav-padding;
font-size: @nav-font-size;
.logo {
width: @logo-width;
}
ul {
list-style-type: none;
display: flex;
li {
padding: 0 10px;
a {
padding-bottom: 2px;
text-decoration: none;
color: #333;
transition: @hover-transition;
&:hover {
border-bottom: 2px solid #000;
}
}
}
&.main-menu {
flex: 1;
margin-left: @menu-margin-left;
}
}
}
.btn{
cursor:pointer;
display:inline-block;
padding:@btn-padding;
background:#fff;
font-size:@btn-font-size;
text-decoration:none;
transition:@hover-transition;
&:hover{
opacity:0.9;
}
}
.dark{
color:#fff;
.btn{
background:#f4f4f4;
color:#333;
}
}
.showcase{
width:100%;
height:@showcase-height;
.background-cover();
background-image: url('https://i.ibb.co/zGSDGCL/slide1.png');
.flex-center();
flex-direction: column;
justify-content: flex-end;
text-align: center;
padding-bottom: 50px;
margin-bottom: 20px;
h2,p{
margin-bottom:10px;
}
.btn{
margin-bottom: 10px;
}
}
.home-cards{
display:grid;
grid-template-columns: repeat(4, 1fr) ;
gap:@grid-gap;
margin-bottom:40px;
img{
width:100%;
height: auto;
object-fit: cover;
margin-bottom: 20px;
}
h3{
margin-bottom: 5px;
}
a{
display:inline-block;
padding-top:10px;
font-weight:bold;
color:#0067b8;
text-decoration:none;
text-transform: uppercase;
transition:@hover-transition;
&:hover{
margin-left:10px;
}
}
}
.xbox {
width: 100%;
height: @xbox-height;
.background-cover();
background-image: url('https://i.ibb.co/tBJGPD9/xbox.png');
margin-bottom: 20px;
.flex-center();
flex-direction: column;
.content {
width: 40%;
padding: 50px 0 0 30px;
}
p, .carbon p {
margin: 10px 0 20px;
}
}
// Carbon 区域
.carbon {
width: 100%;
height: @carbon-height;
.background-cover();
background-image: url('https://i.ibb.co/zVqhWn2/card5.png');
margin-bottom: 20px;
display: flex;
.content {
width: 40%;
margin-left: 20px;
margin-top: 20px;
}
.btn {
margin-top: 30px;
}
}
// 链接区域
.links {
.links-inner {
background: #f4f4f4;
display: grid;
grid-template-columns: repeat(5, 1fr);
}
}
// 响应式设计
@media (max-width: 500px) {
.home-cards {
grid-template-columns: 1fr;
}
.links {
.links-inner {
grid-template-columns: 1fr;
ul {
margin-bottom: 20px;
}
}
}
}
// 菜单按钮
.menu-btn {
cursor: pointer;
position: absolute;
top: 10px;
right: 30px;
z-index: 2;
display: none;
}
实现成功