flex布局是我们开发中很常用的一种布局模式,他可以快速实现一些我们需要的布局结构,相比传统的定位布局节省很多代码,相信大多数小伙伴都是用得得心应手了,如果用一般css写flex布局,会涉及很多宽度高度的计算,带来许多烦恼,本文将带领小伙伴用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; &:nth-of-type(@{length}n) { margin-right: 0px; }}
其中nth-of-type(@{length}n)选择了每行的最后一个盒子,并将其右外边距设置d0px
当点击切换后,首先每行显示两个小盒子,外层盒子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布局的一种解决方案,当然还有其他方案,也许还有更佳方案,本文仅是我的一种想法,如有纰漏,还请见谅,咋们评论区交流。