利用Less快速实现flex布局

322 阅读4分钟

flex布局是我们开发中很常用的一种布局模式,他可以快速实现一些我们需要的布局结构,相比传统的定位布局节省很多代码,相信大多数小伙伴都是用得得心应手了,如果用一般cssflex布局,会涉及很多宽度高度的计算,带来许多烦恼,本文将带领小伙伴用less来快速实现flex布局.

  • 布局需求

想象这样一个需求,一个大盒子里面有十个正方形小盒子,我们需要小盒子在大盒子里面整齐排列,不管是一行两个、一行三个、一行四个还是五个,都要整齐排列,并且每行第一个最后一个紧挨着大盒子,每行所有盒子间隔一共50px,想象一下这个功能用css将会有多复杂,而less中的变量和函数将会为我们带来极大便利,接下来,我将带领小伙伴们用less快速实现。

  • less解决方案

HTMLl结构及切换每行小盒子数逻辑:

<button class="toggle">切换</button>
  <ul class="box">
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
  </ul>
let btn = document.querySelector('.toggle');
let box = document.querySelector('.box');
let count = 1;
const update = () => {
  count += 1;
  if (count > 5) {
    count = 1;
  }
  if (count === 1) {
    btn.innerHTML = "未指定"
    box.className = "box"
  } else {
    btn.innerHTML = `每行${count}个`;
    box.className = `box col-${count}`
  }
}
btn.addEventListener('click',update);

设置初始化样式:

* {  
  margin:0px;
  padding: 0px;
  box-sizing: border-box;
}

.box {
  width: 600px;
  margin: 100px auto;
  outline: 1px solid;
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  align-content: flex-start;
  
  .item {
  	width: 100px;
    border: 1px solid; 
    height: 100px;
    background-color: pink;
  }
}

考虑到切换布局后,每行所有小盒子的间隔总共为50px,我们可以用一个变量@restSpace来保存,每行小盒子数为@length,那么下盒子的间隔就是@restSpace/(@length - 1) * 1px,每个小盒子的高度便为(600 - @restSpace) / @length * 1px,利用less的函数特性,小盒子样式为:

@restSpace:50;

.demo (@length) {
  @margin:(@restSpace) / (@length - 1) * 1px;
  width:(600 - @restSpace) / @length * 1px;
  margin-right:@margin;
  margin-bottom:@margin;
  
  // 每行最后一个小盒子右外边距为 0px
  &:nth-of-type(@{length}n) {
    margin-right: 0px;
  }
}

当点击切换后,首先每行显示两个小盒子,外层盒子class="box col-2",那么此时页面布局样式在前面基础上加上:

.box {
  &.col-2 .item {
    // 	调用上面小盒子的样式函数,传入每行两个盒子
    .demo(2); 
  }
}

上效果图: 考虑到布局的变换,每行小盒子数量会变化,我们将上一步封装为函数,传入每行小盒子的数量,并循环创建每行两个、三个、四个、五个盒子情况下的样式:

// @i:2 从每行两个小盒子开始
.demoPro(@length,@i:2) when (@i <= @length){
  // .col-@{i} 根据每行小盒子数拼接class名  
  &.col-@{i} .item {
    .demo(@i);
  }
  .demoPro(@length,@i + 1);
}

// @length为5,循环创建每行2-5个盒子布局的样式
.demoPro(5);

至此,我们的所有对应的布局全部完成,看看效果吧: 可以看到,不管是每行两个、三个、四个还是五个,整个布局都是整齐协调的,且每行第一个第一个和最后一个紧挨着外层盒子,每行所有间隔总和不变,每个小盒子随着布局伸缩,这就是less的变量以及函数的特性带来的好处,可以节省很多css代码,且计算方便。

  • less完整代码

下面我们来看一看完整的less代码:

*{
  margin:0px;
  padding: 0px;
  box-sizing: border-box;
}

.toggle {
  display: block;
  margin: 30px auto; 
  width: 100px;
}

.box {
  width: 600px;
  margin: 100px auto;
  outline: 1px solid;
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  align-content: flex-start;

  .item {
    width: 100px;
    border: 1px solid;
    height: 100px;
    background-color: pink;
  }
  
  @restSpace:50;
  
  .demo (@length) {
    @margin:(@restSpace) / (@length - 1) * 1px;
    width:(600 - @restSpace) / @length * 1px;
    margin-right:@margin;
    margin-bottom:@margin;

    &:nth-of-type(@{length}n) {
      margin-right: 0px;
    }
  }

  .demoPro(@length,@i:2) when (@i <= @length){
    &.col-@{i} .item {
      .demo(@i);
    }
    .demoPro(@length,@i + 1);
  }

  .demoPro(5);
}
  • css代码

为了方便理解以及对比,我把css实现代码(根据less生成)附在后面,以供小伙伴们参考:

* {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
}
.toggle {
  display: block;
  margin: 30px auto;
  width: 100px;
}
.box {
  width: 600px;
  margin: 100px auto;
  outline: 1px solid;
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  align-content: flex-start;
}
.box .item {
  width: 100px;
  border: 1px solid;
  height: 100px;
  background-color: pink;
}
.box.col-2 .item {
  width: 275px;
  margin-right: 50px;
  margin-bottom: 50px;
}
.box.col-2 .item:nth-of-type(2n) {
  margin-right: 0px;
}
.box.col-3 .item {
  width: 183.33333333px;
  margin-right: 25px;
  margin-bottom: 25px;
}
.box.col-3 .item:nth-of-type(3n) {
  margin-right: 0px;
}
.box.col-4 .item {
  width: 137.5px;
  margin-right: 16.66666667px;
  margin-bottom: 16.66666667px;
}
.box.col-4 .item:nth-of-type(4n) {
  margin-right: 0px;
}
.box.col-5 .item {
  width: 110px;
  margin-right: 12.5px;
  margin-bottom: 12.5px;
}
.box.col-5 .item:nth-of-type(5n) {
  margin-right: 0px;
}
  • 总结

Less使用嵌套,使得代码更短、更干净,层级关系更明确,易度性强,加之其提供了一系列运算符、变量、函数等,使布局样式的编更快,更省时,更易于维护。事实上,在绝大多数情况下,较之css来得更加的优雅,初用时就会觉得徒增麻烦,后面就会发现是真的——香!!!

本文是来自前端菜鸟自学前端过程中的第一篇技术博客,是我用less实现flex布局的一种解决方案,当然还有其他方案,也还有更佳方案,本文仅是我的一种想法,如有纰漏,还请见谅,欢迎来评论区交流。