【问题标题】:How to set gaps (gutters) in a flex container?如何在弹性容器中设置间隙(排水沟)?
【发布时间】:2019-11-20 11:43:29
【问题描述】:

我正在尝试创建某种弹性容器的通用组件。该组件由容器及其子元素组成。

如果一行中的孩子太多,那些空间不足的孩子会转到第二行。它可以通过 flexbox 轻松实现,但我也希望能够在元素之间设置间距。并且一行的第一个和最后一个元素不应该分别有左边距和右边距。

我使用负边距技术来做到这一点,但这里的问题是,如果容器太大,右边距会引发溢出问题。我可以通过添加overflow: hidden 来解决这个问题,以切断负边距,但它会引发容器内溢出项目(下拉菜单等)的问题。

所以现在我正在寻找银弹,可以满足这个要求的实现:

  • 一行中有多个项目。项目的宽度可能不同。
  • 如果某些项目没有足够的空间,它们会转到下一行。
  • 项目(边距)之间存在间隙,第一个和最后一个项目分别没有左右边距。
  • 容器内可以放置溢出内容(下拉菜单),所以我不能使用overflow: hidden
  • 可以使用css网格和flexbox

这是我对这个问题的解决方案: https://jsbin.com/gabumax

这里是示例代码:

.container {
  overflow: hidden;
}

.wrapper {
  margin: -10px;
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex: 0 0 auto;
  padding: 10px;
  background-color: red;
  margin: 10px;
}
<div class="container">
  <div class="wrapper">
    <div class="item">Width of items can vary</div>
    <div class="item">This example works</div>
    <div class="item">But there is a problem</div>
    <div class="item">Dye to overlow:hidden</div>
    <div class="item">It is impossible to place here</div>
    <div class="item">Overflowing content</div>
    <div class="item">Such as dropdowns</div>
  </div>
</div>

它有效,但这里唯一的缺点是overlow: hidden。因此,我不能在这里放置下拉列表和其他溢出的内容。

有更好的解决方案吗?提前致谢。

【问题讨论】:

    标签: html css flexbox css-grid


    【解决方案1】:

    Flexbox 在这里不是您的最佳选择。正如您所描述的,排水沟解决方案笨拙且效率低下。

    使用 CSS Grid 可以实现干净高效的解决方案。

    Grid 在这个领域暂时胜过 flexbox,因为 Grid 接受 gap 属性。这些属性在 flex 中尚不可用,但随着浏览器继续实现CSS Box Alignment Modulegap 属性将在多个盒子模型(包括 flex)中可用。

    § Gaps Between Boxes

    虽然marginpadding 可用于指定视觉间距 围绕单个盒子,有时更方便全局 指定给定布局上下文中相邻框之间的间距, 特别是当盒子之间的间距不同时 在第一个/最后一个盒子和容器边缘之间。

    gap 属性及其row-gapcolumn-gap 子属性, 为多列、弹性和网格布局提供此功能。

    .wrapper {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      grid-auto-rows: 50px;
      grid-gap: 10px;
    }
    
    .item {
      padding: 10px;
      background-color: red;
    }
    
    body {
      margin: 0;
    }
    <div class="container">
      <div class="wrapper">
        <div class="item">Width of items can vary</div>
        <div class="item">This example works</div>
        <div class="item">But there is a problem</div>
        <div class="item">Dye to overlow:hidden</div>
        <div class="item">It is impossible to place here</div>
        <div class="item">Overflowing content</div>
        <div class="item">Such as dropdowns</div>
      </div>
    </div>

    jsFiddle demo

    【讨论】:

    • 感谢您的回答!但是 css-grid 有严重的缺点:使用这种技术我不能拥有不同宽度的项目。我的目标是拥有多个不同宽度的项目(每个项目都有自己的宽度,具体取决于它的内容)。我可以用 css 网格实现这一点吗?
    • 尝试在minmax() 函数中将1fr 切换为min-content。您有多种选择。只是取决于您的具体要求。
    • Firefox 现在在 Flex 布局中支持 gapcaniuse.com/#feat=flexbox-gap
    【解决方案2】:

    为避免显示滚动条,您可以仅在左侧和顶部设置负边距。

    body {
      margin: 0;
    }
    
    .container {
      width:31.7em;
      max-width:100%;
      margin:auto;;
      background:yellow; 
    }
    
    .wrapper {
       display: flex;
      flex-wrap: wrap;
      margin-left:-10px;
      margin-top:-10px;
    }
    
    .item {
      flex: 0 0 auto;  
      padding: 10px;  
      background-color: red;  
      margin:10px  0  0 10px;
    }
    <div class="container">
      <div class="wrapper">
        <div class="item">Width of items can vary</div>
        <div class="item">This example works</div>
        <div class="item">But there is a problem</div>
        <div class="item">Dye to overlow:hidden</div>
        <div class="item">It is impossible to place here</div>
        <div class="item">Overflowing content</div>
        <div class="item">Such as dropdowns</div>
    
      </div>
    </div>

    如果文档目录是 rtl,则为负右边距

    body {
      margin: 0;
      direction:rtl;
    }
    
    .container {
      width:31.7em;
      max-width:100%;
      margin:auto;;
      background:yellow; 
    }
    
    .wrapper {
       display: flex;
      flex-wrap: wrap;
      margin-right:-10px;
      margin-top:-10px;
    }
    
    .item {
      flex: 0 0 auto;  
      padding: 10px;  
      background-color: red;  
      margin:10px 10px  0  0;
    }
    <div class="container">
      <div class="wrapper">
        <div class="item">Width of items can vary</div>
        <div class="item">This example works</div>
        <div class="item">But there is a problem</div>
        <div class="item">Dye to overlow:hidden</div>
        <div class="item">It is impossible to place here</div>
        <div class="item">Overflowing content</div>
        <div class="item">Such as dropdowns</div>
    
      </div>
    </div>

    【讨论】:

    • 这是一个非常简单的解决方案。你救了我整个世界的痛苦:) 谢谢!!
    【解决方案3】:

    使用gap/row-gap/column-gap

    .wrapper {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }
    

    查看更多here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2019-10-07
      相关资源
      最近更新 更多