【前端笔记】CSS预处理语言 LESS

官网: 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;
  }

实现成功

相关推荐
咒法师无翅鱼5 分钟前
【大英赛】大英赛准备笔记
笔记
小桥风满袖23 分钟前
工作多年,我学会了写防御性CSS
css
咪库咪库咪25 分钟前
CSS过渡与动画
前端
今天阳光明媚吗28 分钟前
STM32HAL库笔记
笔记·stm32
前端康师傅29 分钟前
CSS基础教程-性能优化
前端·css
掘金用户897233 分钟前
微信小程序 扫码+拍照
前端
睡不着的可乐34 分钟前
Ant Design Vue 表格复杂数据合并单元格
前端·vue.js·ant design
upsilon34 分钟前
React-router V7(配置路由)
前端·react.js
江城开朗的豌豆36 分钟前
手把手教你定制Vue3项目的Git提交规范:cz-customizable实战
前端·git·程序员
不简说37 分钟前
sv-print可视化打印组件不完全指南④
前端·javascript·vue.js