乐趣区

不怕你用不上!CSS 列表项布局技巧

编者按:为了不引入 HTML 标签自身的样式,本文未考虑 HTML 语义化的提倡,以使得行文与示例代码更加简洁。这是文章写作需要,而非代码风格示范。

在开发中我们经常会遇到关于如何展示列表的问题,例如:
图片选择器列表

人员部门选择列表

工作状态列表

通用方法
为了让其看起来更加舒适美观,通常我们会在每个列表项上添加 margin-right 和 margin-bottom 属性来隔开它们,然后一行超过容器长度后进行换行
那么在各种情况下,如何处理列表项中 margin-right 和 margin-bottom,让列表间隔和换行看起来更加自然美观是本篇的重点
各种情况下的布局
元素宽度已知,即知道每行最多多少个,且所有元素都在一个容器中

思路:item 在一个容器中,每第三个去掉 margin-right,最后三个取消 margin-bottom(如最后一行不满 3 个也不影响)
关键代码

<div class=’container’>
<div class=’item’> 宽度已知,最多放三个 </div>
<div class=’item’> 宽度已知,最多放三个 </div>
<div class=’item’> 宽度已知,最多放三个 </div>

</div>

<style>
/* scss code */
.container {
.item {
margin-right: 30px;
margin-bottom: 20px;

&:nth-child(3n) {margin-right: 0;}
&:nth-last-child(-n+3) {margin-bottom: 0;}
}
}
</style>
运行截图

完整代码:元素宽度已知,所有元素都在一个容器

元素宽度已知 或 未知,且元素按照行数在相应容器中

思路:最后一个 container 去掉 margin-bottom,最后一个 item 去掉 magin-right
关键代码

<div class=’container’>
<div class=’item’></div>
<div class=’item’></div>
</div>
<div class=’container’>
<div class=’item’></div>
<div class=’item’></div>
<div class=’item’></div>
</div>
<div class=’container’>
<div class=’item’></div>
</div>

<style>
/* scss code */
.container {
margin-bottom: 20px;
&:last-child {margin-bottom: 0;}

.item {
margin-right: 30px;
&:last-child {margin-right: 0;}
}
}
</style>
运行截图

完整代码:元素宽度已知或未知,且按照行数在相应容器

元素宽度未知,即不知道一行最多多少个,且所有元素都在一个容器中,常见于 flex 布局
法 1:Flex 布局

思路:利用 flex 布局的 justify-content 主轴属性来控制元素的间距
缺点:flex 虽然强大,但是面对 长度不定的列表项布局 还是不能很好满足要求
关键代码

<div class=’container’>
<div class=’item’> 两个可以成一行 </div>
<div class=’item’> 两个可以成一行 </div>
<div class=’item’> 这三个字 </div>
<div class=’item’> 独成一行呀独成一行呀独成一行呀独成 </div>
<div class=’item’> 两个才能成一行呀 </div>
<div class=’item’> 四个 </div>
</div>

<style>
/* scss code */
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between; /* 可以尝试其他值,但效果仍不好 */

.item {
/* margin-right: 30px; 可以不用 m-r,由 flex 来控制左右间距 */
margin-bottom: 20px;
}
}
运行截图

完整代码:元素宽度已知或未知,且按照行数在相应容器

法 2:负 margin

接下来介绍 负 margin 方法,可以很好的解决 长度不定的列表项布局 问题
思路:用一个 wrapper 包在最外层,container 设置 负的 margin 来抵消 item 的 外边距

参考链接:https://segmentfault.com/q/1010000005882081/a-1020000005894468
关键代码
<div class=”wrapper”>
<div class=’container’>
<div class=’item’> 两个才能成一行呀 </div>
<div class=’item’> 两个才能成一行呀 </div>
<div class=’item’> 这三个字 </div>
<div class=’item’> 独成一行呀独成一行呀独成一行呀独 </div>
<div class=’item’> 两个才能成一行呀 </div>
<div class=’item’> 四个 </div>
</div>
</div>

<style>
/* scss code */
.wrapper {
padding: 10px;
border: 2px solid rgb(240, 103, 103);

.container {
display: flex;
flex-wrap: wrap;
margin-right: -30px;
margin-bottom: -20px;

.item {
margin-right: 30px;
margin-bottom: 20px;
}
}
}
</style>
运行截图

完整代码:法 2:元素宽度未知,且所有元素都在一个容器

总结
多多利用 css3 属性来帮助我们更好的布局列表,避免使用 js 控制列表项,做到 css 与 js 解耦,更利于项目的维护
以上可能未包含所有情况,欢迎提出或者分享其他更好的解决办法

文 / Lawler61Learn and to learn.Github:https://github.com/lawler61 作者博客:www.freeze61.me 编 / 荧声

本文由创宇前端作者授权发布,版权属于作者,创宇前端出品。欢迎注明出处转载本文。文章链接:https://knownsec-fed.com/2018…
想要订阅更多来自知道创宇开发一线的分享,请搜索关注我们的微信公众号:创宇前端(KnownsecFED)。欢迎留言讨论,我们会尽可能回复。

欢迎点赞、收藏、留言评论、转发分享和打赏支持我们。打赏将被完全转交给文章作者。
感谢您的阅读。

退出移动版