【问题标题】:How to use flex-start but with the margin space-around would provide?如何使用 flex-start 但可以提供周围的边距空间?
【发布时间】:2018-07-08 07:07:10
【问题描述】:

当使用space-around 作为justify-content 的参数时,它将在容器内均匀地分隔项目。我想要的是左侧的所有项目 start (flex-start),但具有与space-around 相同的边距。

我认为这说明了问题:

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  width: 100%;
  border: 1px solid red;
}

.item {
  flex: 0 0 16%; /*6 items per line leaving some for margin*/
  border: 1px solid black;
  box-sizing: border-box;
}
<div class="container">
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
</div>

我想要的是让第二行换行并占据前 2 列。我知道我可以在 .item 类上指定一个填充并将 flex 属性设置为 flex-start,但我不能总是 100% 确定填充的大小,因为它可以针对多个设备进行缩放。

这可以这样证明:

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  width: 100%;
  border: 1px solid red;
}

.item {
  flex: 0 0 16%; /*6 items per line leaving some for padding*/
  border: 1px solid black;
  box-sizing: border-box;
  margin-right: 0.66%
}
<div class="container">
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
</div>

红色边框之间项目的整体间距不对,又不知道具体数值,不知道怎么设置成这样。

【问题讨论】:

  • 您在寻找justify-content: space-between 吗?
  • 否,因为在我的第一个示例中,这会使第二行的 2 个项目转到第一列中的一个和最后一列中的一个。
  • youtube.com/watch?v=0e02dl66PYo 这真的很好帮助你了解你可以用弹性盒子做什么
  • @BradleyCoupland 它是否涵盖了我的特定场景(它是一个 20 分钟的视频)?有很多资源可以解释 flexbox,但我没有找到任何涵盖这种特定场景的资源。
  • 这是 flex 的限制,如果您希望第二行(假设动态的项目数量)向左对齐,那么最好自己指定边距。或者(这是我在工作中所做的并且我们的开发团队同意这一点),您可以添加空项目,以便每行始终有 6(或 n 个)项目。这样它就会一直正确对齐。这已经在这里问了stackoverflow.com/questions/16377972/…

标签: html css flexbox


【解决方案1】:

不幸的是,这是 flex 的限制

解决方法

您可以添加空的弹性项目,这样每行总是有 6 个(或 n 个)项目。它是额外的 html,但这可以避免您为响应式设计设置不同宽度的边距。

<div class="container">

  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item">ITEM</div>

  <div class="item">ITEM</div>
  <div class="item">ITEM</div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>

</div>

在您的媒体查询范围内,您可以为您的项目定义不同的宽度并创建一个隐藏项目类,以便在该宽度下将其隐藏。

我工作中的一个例子

large 和 medium 有 12 列网格,small 有 6 列网格,phone 有 4 列。它使用的是 Freemarker 宏,但这只是为了向您展示如何设置它,下面代表我们支持的任何宽度上的 1 行

<div class="<@grid large="1" medium="11" small="5" phone="0" />"></div>
<div class="<@grid large="11" medium="1" small="1" phone="4" />"></div>

上面的最终输出是

<div class="large-col-1 medium-col-11 small-col-5 phone-col-0"></div>
<div class="large-col-1 medium-col-1 small-col-1 phone-col-4"></div>

这些类中的每一个都只在它们自己的媒体查询范围内定义。

您可以使用 css 网格来解决此问题,但请先检查浏览器支持

【讨论】:

    【解决方案2】:

    不能用 flexbox 来完成,至少在没有超具体的 hack 的情况下不能做到:一些常见的方法是 javascript spaghetti 或容器上的空 div/伪元素,但所有这些都非常脆弱,远非动态的理想上下文。

    但是你可以使用类似 flex 的网格,如果你希望项目拉伸并保持恒定的网格间距,请使用 autofit minmax

    .grid{
      /*sets the container as a grid with variable number of columns*/
      display:grid;
      grid-template-columns: repeat(auto-fill, minmax(160px,1fr));
      grid-gap:1em;
    }
    

    https://codepen.io/facundocorradini/pen/XVMLEq

    或者只是为元素添加一个固定的宽度,如果你想要它们的空间样式,甚至可以添加一个 justify-items: center。链接笔上的示例。

    以上示例具有可自动调整的列数,但如果您希望将其固定为 16%,只需声明这些列即可。

    一个好的策略是使用网格方法并让 flexbox 处理不支持它的浏览器的回退。幸运的是网格是extremely smart at overriding the fallbacks,所以应该很容易。

    【讨论】:

      【解决方案3】:

      如前所述,可以添加ghost elements 来填充最后一行,但在这种情况下,不需要用未使用的元素污染标记,只需使用nth-child 选择器并简单地计算所需的左侧除每行中的第一个项目外,所有项目的边距。

      计算是通过从父项的全宽(100% -中删除项目宽度的总和(16% * 6)),然后将剩下的除以间隙量/ 5)

      .item:not(:nth-child(6n+1)) 将选择除每 6 次以外的所有项目,从第 1 次开始(例如第 1 次、第 7 次、第 13 次等)。

      如果每行中的项目数会发生变化,请使用媒体查询来调整6n+1 选择器和计算值。

      堆栈sn-p

      .container {
        display: flex;
        flex-wrap: wrap;
        width: 100%;
        border: 1px solid red;
      }
      
      .item {
        flex: 0 0 16%; /*6 items per line leaving some for margin*/
        border: 1px solid black;
        box-sizing: border-box;
      }
      
      .item:not(:nth-child(6n+1)) {
        margin-left: calc( (100% - (16% * 6)) / 5 );          /*  added  */
      }
      <div class="container">
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
        <div class="item">ITEM</div>
      </div>

      【讨论】:

      • 正确 - 已经接受了这个作为答案,因为纯 CSS 解决方案更好。
      猜你喜欢
      • 2023-02-16
      • 2021-07-16
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      相关资源
      最近更新 更多