设置弹性框项目之间距离的更好方法

CSS

GilTomL

2020-03-16

要设置我在容器margin: 0 5px.itemmargin: 0 -5px容器上使用的flexbox项之间的最小距离对我来说,这似乎是一种hack,但是我找不到更好的方法来做到这一点。

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  margin: 0 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

第1817篇《设置弹性框项目之间距离的更好方法》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

17个回答
布雷西 2020.03.16

假设:

  • 您需要带包装的4列网格布局
  • 项目数不一定是4的倍数

在第1、5、9个项目以外的所有项目上设置左页边距;并在每个项目上设置固定宽度。如果左边距为10px,则每行在4个项目之间将有30px的边界,可以按以下方式计算项目的宽度百分比:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

对于涉及flexbox最后一行的问题,这是一个不错的解决方法。

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

阿飞宝儿猴子 2020.03.16

Columnify-N列的独奏类

Flexbox和SCSS

.columnify {
  display: flex;

  > * {
    flex: 1;

    &:not(:first-child) {
      margin-left: 2rem;
    }
  }
}

Flexbox和CSS

.columnify {
  display: flex;
}

.columnify > * {
  flex: 1;
}

.columnify > *:not(:first-child) {
  margin-left: 2rem;
}
<div class="columnify">
  <div style="display: inline-block; height: 20px; background-color: blue;"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>

JSFiddle

Stafan 2020.03.16

我发现最简单的方法是使用百分比,并且仅允许边距增加宽度

这意味着如果您使用示例,则最终会得到类似的结果

#box {
   display: flex;
}

.item {
   flex: 1 1 23%;
   margin: 0 1%;
}

确实意味着您的值基于宽度,但这可能并不适合所有人。

西里Eva伽罗 2020.03.16

为什么不这样做呢?

.item + .item {
    margin-left: 5px;
}

这使用相邻的同级选择器,为.item除第一个元素之外的所有元素赋予a margin-left多亏了flexbox,这甚至导致了同样宽的元素。当然,这也可以通过垂直放置的元素来完成margin-top

Tony小卤蛋 2020.03.16

这是我的解决方案,不需要在子元素上设置任何类:

.flex-inline-row {
    display: inline-flex;
    flex-direction: row;
}

.flex-inline-row.flex-spacing-4px > :not(:last-child) {
    margin-right: 4px;
}

用法:

<div class="flex-inline-row flex-spacing-4px">
  <span>Testing</span>
  <span>123</span>
</div>

除了上面给出的内联示例外,相同的技术还可以用于常规的flex行和列,并使用除4px以外的其他间距类进行扩展。

EvaDavaid 2020.03.16

在解决方案中使用Flexbox时,我已将该justify-content属性用作父元素(容器),并且已在各项的flex-basis属性内指定了边距检查以下代码片段:

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-bottom: 10px;
}

.item {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #999;
}

.item-1-4 {
  flex-basis: calc(25% - 10px);
}

.item-1-3 {
  flex-basis: calc(33.33333% - 10px);
}

.item-1-2 {
  flex-basis: calc(50% - 10px);
}
<div class="container">
  <div class="item item-1-4">1</div>
  <div class="item item-1-4">2</div>
  <div class="item item-1-4">3</div>
  <div class="item item-1-4">4</div>
</div>
<div class="container">
  <div class="item item-1-3">1</div>
  <div class="item item-1-3">2</div>
  <div class="item item-1-3">3</div>
</div>
<div class="container">
  <div class="item item-1-2">1</div>
  <div class="item item-1-2">2</div>
</div>

樱泡芙 2020.03.16

根据#ChromDevSummitFlexbox有一个gap属性实现,尽管目前(2019年11月14日)仅在Firefox中支持但应尽快在Chrome中实现:

在此处输入图片说明

现场演示

我也会在Chrome上也更新我的答案。

逆天AGreen 2020.03.16

最终,他们会将gap属性添加到flexbox。在此之前,您可以使用CSS网格代替它已经具有的gap属性,并且只有一行。比处理利润更好。

神无LEY 2020.03.16

柔性容器-x(负)余量柔性物品X(正)余量填充既导致所希望的视觉效果:弹性件具有2X的固定间隙仅之间彼此。

无论是在弹性项目上使用边距还是填充,这似乎只是一个优先事项。

在此示例中,为了保持固定的间隙,对伸缩项进行了动态缩放:

.flex-container { 
  margin: 0 -5px;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.flex-item {
  margin: 0 5px; // Alternatively: padding: 0 5px;
  flex: 1 0 auto;
}
神乐米亚蛋蛋 2020.03.16

我已经将其用于包装和固定宽度的列。这里的关键是calc()

SCSS样本

$gap: 10px;

dl {
  display: flex;
  flex-wrap: wrap;
  padding: $gap/2;

  dt, dd {
    margin: $gap/2;}

  dt { // full width, acts as header
    flex: 0 0 calc(100% - #{$gap});}

  dd { // default grid: four columns 
    flex: 0 0 calc(25% - #{$gap});}

  .half { // hall width columns
    flex: 0 0 calc(50% - #{$gap});}

}

完整的Codepen样本

阿飞Pro 2020.03.16

从sawa的答案继续,这是一个略有改进的版本,可让您在项目之间设置固定的间距,而没有周围的空白。

http://jsfiddle.net/chris00/s52wmgtq/49/

还包括Safari的“ -webkit-flex”版本。

.outer1 {
    background-color: orange;
    padding: 10px;
}

.outer0 {
    background-color: green;
    overflow: hidden;
}

.container
{
    display: flex;
    display: -webkit-flex;
    flex-wrap: wrap;    
    -webkit-flex-wrap: wrap;
    background-color: rgba(0, 0, 255, 0.5);
    margin-left: -10px;
    margin-top: -10px;
}

.item
{
    flex-grow: 1;
    -webkit-flex-grow: 1;
    background-color: rgba(255, 0, 0, 0.5);
    width: 100px;
    padding: 10px;
    margin-left: 10px;
    margin-top: 10px;
    text-align: center;
    color: white;
}

<div class="outer1">
    <div class="outer0">
        <div class="container">
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
        </div>
    </div>
</div>
飞云小胖 2020.03.16

我已经找到了基于通用同级选择器的解决方案~,并允许无限嵌套。

有关实际示例,请参见此代码笔

基本上,在列容器中,每个子项之前都有另一个子项会获得最高利润。同样,在每个行容器中,每个子项之前的另一个子项都有一个左边距。

.box {
  display: flex;
  flex-grow: 1;
  flex-shrink: 1;
}

.box.columns {
  flex-direction: row;
}

.box.columns>.box~.box {
  margin-left: 5px;
}

.box.rows {
  flex-direction: column;
}

.box.rows>.box~.box {
  margin-top: 5px;
}
<div class="box columns">
  <div class="box" style="background-color: red;"></div>
  <div class="box rows">
    <div class="box rows">
      <div class="box" style="background-color: blue;"></div>
      <div class="box" style="background-color: orange;"></div>
      <div class="box columns">
        <div class="box" style="background-color: yellow;"></div>
        <div class="box" style="background-color: pink;"></div>
      </div>
    </div>
    <div class="box" style="background-color: green;"></div>
  </div>
</div>

斯丁泡芙 2020.03.16

假设您要10px在项目之间设置空间,则可以只设置.item {margin-right:10px;}所有项目,然后在最后一个项目上重置它.item:last-child {margin-right:0;}

您还可以使用常规同级~或下一个+同级选择器在除第一个.item ~ .item {margin-left:10px;}第二个以外的项目上设置左页边距.item:not(:last-child) {margin-right: 10px;}

Flexbox非常聪明,可以自动重新计算并平均分配网格。

body {
  margin: 0;
}

.container {
  display: flex;
}

.item {
  flex: 1;
  background: gray;
  height: 50px;
}

.item:not(:last-child) {
  margin-right: 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

如果要允许使用flex wrap,请参见以下示例。

body {
  margin: 0;
}

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

.item {
  flex: 0 0 calc(50% - 10px);
  background: gray;
  height: 50px;
  margin: 0 0 10px 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

小宇宙蛋蛋 2020.03.16

您可以使用透明边框。

我在尝试构建Flex网格模型时已经考虑了这个问题,该模型可以回退到旧浏览器的table + table-cell模型。在我看来,用于装订线槽的边框是最佳的选择。即表格单元格没有边距。

例如

.column{
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 10px solid transparent;
}

另请注意,您需要min-width: 50px;使用flexbox。Flex模型将无法处理固定大小,除非您flex: none;对想要固定的特定子元素进行处理,从而将其排除在外"flexi"http://jsfiddle.net/GLpUp/4/ 但是所有列flex:none;都不再是flex模型。这是更接近flex模型的内容:http : //jsfiddle.net/GLpUp/5/

因此,如果您不需要旧版浏览器的表格单元回退,则实际上可以正常使用页边距。http://jsfiddle.net/GLpUp/3/

background-clip: padding-box;使用背景时必须进行设置,否则背景将流入透明边框区域。

番长前端猴子 2020.03.16

Flexbox和CSS Calc具有多行支持

您好,以下是适用于所有支持flexbox的浏览器的工作解决方案。无负边距。

小提琴演示

   
.flexbox {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flexbox > div {
  /*
    1/3  - 3 columns per row
    10px - spacing between columns 
  */
  box-sizing: border-box;
  margin: 10px 10px 0 0;
  outline: 1px dotted red;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}

/*
  align last row columns to the left
  3n - 3 columns per row
*/
.flexbox > div:nth-child(3n) {
  margin-right: 0;
}

.flexbox::after {
  content: '';
  flex: auto;
}

/*
  remove top margin from first row
  -n+3 - 3 columns per row 
*/
.flexbox > div:nth-child(-n+3) {
  margin-top: 0;
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>

注意,使用SASS可以使此代码更短

更新2020.II.11左最后一行中的对齐列

更新2020.II.14在最后一行中删除了下边距

有壳网 2020.03.16

这不是黑客。引导程序及其网格也使用了相同的技术,尽管引导程序使用padding作为其cols来代替空白。

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}
乐米亚 2020.03.16
  • Flexbox的利润率没有下降。
  • Flexbox没有类似于border-spacing表的任何东西(除了CSS属性gap,大多数浏览器都无法很好地支持CSS属性caniuse

因此,实现您的要求会更加困难。

以我的经验,不使用:first-child/ :last-child且不作任何修改就flex-wrap:wrap可以工作的“最干净”的方式padding:5px在容器和margin:5px孩子身上设置。这将10px在每个孩子之间以及每个孩子与其父母之间产生差距。

演示版

.upper
{
  margin:30px;
  display:flex;
  flex-direction:row;
  width:300px;
  height:80px;
  border:1px red solid;

  padding:5px; /* this */
}

.upper > div
{
  flex:1 1 auto;
  border:1px red solid;
  text-align:center;

  margin:5px;  /* and that, will result in a 10px gap */
}

.upper.mc /* multicol test */
{flex-direction:column;flex-wrap:wrap;width:200px;height:200px;}
<div class="upper">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

<div class="upper mc">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android