CSS 列表项布局技巧

css-item-layout

github 原文地址(实时更新):CSS 列表项布局技巧

感谢 创宇前端 的推广:juejin.im/post/5c171f…

一、现有情况

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

  • 人员部门选择列表

  • 工作状态列表

二、通用方法

  1. 为了让其看起来更加舒适美观,通常我们会在每个列表项上添加 margin-rightmargin-bottom 属性来隔开它们,然后一行超过容器长度后进行换行

  2. 那么在各种情况下,如何处理列表项中margin-rightmargin-bottom,让列表间隔和换行看起来更加自然美观是本篇的重点

三、各种情况下的布局

元素宽度已知,即知道每行最多多少个,且所有元素都在一个容器中

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

  2. 关键代码

<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; } /* 一行最多几个就填 几n */
      &:nth-last-child(-n+3) { margin-bottom: 0; }
    }
  }
</style>
复制代码
  1. 运行截图

  1. 完整代码

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

  1. 思路:最后一个 container 去掉 margin-bottom,最后一个 item 去掉 margin-right

  2. 关键代码

<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>
复制代码
  1. 运行截图

  1. 完整代码

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

法1:Flex 布局

  1. 思路:利用 flex 布局的 justify-content 主轴属性来控制元素的间距

  2. 缺点:flex 虽然强大,但是面对 长度不定的列表项布局 还是不能很好满足要求

  3. 关键代码

<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;
    }
  }
</style>
复制代码
  1. 运行截图

  1. 完整代码

法2:负margin

  1. 接下来介绍 负margin 方法,可以很好的解决 长度不定的列表项布局 问题

  2. 思路:用一个 wrapper 包在最外层,container 设置 负的 margin 来抵消 item 的 外边距

  1. 关键代码
<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>
</div>

<style>
  /* scss code */
  .wrapper {
    .container {
      display: flex;
      flex-wrap: wrap;
      margin-right: -30px;
      margin-bottom: -20px;

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

  1. 完整代码

flex 布局中元素整体居左,最后几个居右;整体居右,前几个居左;某几个居中

有多少人有过被 justify-self: flex-end; 支配的恐惧,其实没有 justify-self 这个属性啦!

法1:flex: 1 + text-align

  1. 思路:给 flex 布局中的元素设置了 flex: 1,可以类似看成 display: block 元素,所以设置 text-align 就搞定

  2. 关键代码

<div class='container'>
  <div class='item'>第一项</div>
  <div class='item'>第二项</div>
  <div class='item'>第三项</div>
  <div class='item'>最后一项</div>
</div>

<style>
  /* scss code 整体居左,某几个元素居右 */
  .container {
    display: flex;
    justify-content: flex-start; /* 默认为 flex-start */

    .item {
      &:nth-last-child(2) { /* 想让最后几个元素居右就填几 */
        flex: 1;
        text-align: right;
      }
    }
  }
</style>

<style>
  /* scss code 整体居右,某几个元素居左 */
  .container {
    display: flex;
    justify-content: flex-end;

    .item {
      &:nth-child(2) { /* 想让前几个元素居左就填几 */
        flex: 1;
        text-align: left;
      }
    }
  }
</style>

<style>
  /* scss code 整体居左,某几个居中 */
  .container {
    display: flex;

    .item {
      &:nth-child(2) { /* 想从第前几个元素开始居中 */
        flex: 1;
        text-align: right;
      }

      &:nth-child(4) { /* 想从第前几个元素结束居中 */
        flex: 1;
        text-align: left;
      }
    }
  }
</style>
复制代码
  1. 运行截图

  1. 完整代码

法2:margin- auto*

  1. 思路:对于 flex 布局的元素也可以通过 margin 来调整位置

  2. 关键代码(代码基本与 法1 类似,可在完整代码具体查看)

<div class='container'>
  <div class='item'>第一项</div>
  <div class='item'>第二项</div>
  <div class='item'>第三项</div>
  <div class='item'>最后一项</div>
</div>

<style>
  /* scss code 整体居左,某几个元素居右 */
  .container {
    display: flex;

    .item {
      &:nth-last-child(2) { /* 想让最后几个元素居右就填几 */
        margin-left: auto;
      }
    }
  }
</style>

scss code 整体居右,某几个元素居左
...
复制代码
  1. 运行截图

  1. 完整代码

四、总结

  1. 多多利用 css3 属性来帮助我们更好的布局列表,避免使用 js 控制列表项,做到 css 与 js 解耦,更利于项目的维护

  2. 以上可能未包含所有情况,欢迎提出或者分享其他更好的解决办法

转载于:https://juejin.im/post/5bf3b54c6fb9a049fc032324

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值