Targeting flex items on the last or specific row

时间:2017-02-11 13:30:47

标签: html css css3 flexbox

My problem is that I want the flexbox with variable range width, and all works well, but not on the last row. I want the same dimension for all children even where the row is not full of children (the last row).

#products-list {
    position:relative;
    display: flex;
    flex-flow: row wrap;
    width:100%;
}

#products-list .product {
    min-width:150px;
    max-width:250px;
    margin:10px 10px 20px 10px;
    flex:1;
}

I created a dynamic situation in jsFiddle

我的flex div可以缩小到150px并且长到250px,但所有都必须具有相同的大小(显然我想要一个CSS解决方案,我知道JS的方式)。

8 个答案:

答案 0 :(得分:37)

不幸的是,在当前的flexbox迭代(Level 1)中,没有干净的方法来解决最后一行对齐问题。这是一个常见的问题。

在以下行中有一个flex属性是有用的:

  • last-row
  • last-column
  • only-child-in-a-row
  • alone-in-a-column

此问题似乎是Flexbox Level 2的高优先级:

虽然这种行为很难在flexbox中实现,但在 CSS网格布局中简单易行:

如果Grid不是一个选项,这里是一个包含各种flexbox hacks的类似问题的列表:

答案 1 :(得分:2)

作为一种快速而肮脏的解决方案,可以使用:

.my-flex-child:last-child/*.product:last-child*/ {
  flex-grow: 100;/*Or any number big enough*/
}

答案 2 :(得分:1)

您可以在此处尝试使用网格而不是flexbox:

#products-list {

  display: grid;
  grid-gap: 5px;
  grid-template-columns: repeat(auto-fit, minmax(100px, 250px)); //grid automagic
  justify-content: start; //start left

}

Fiddle link

答案 3 :(得分:0)

我使用了这种解决方法,即使它不是很优雅,也没有使用Flexbox的强大功能。

可以在以下条件下进行:

  • 所有项目的宽度相同
  • 项目具有固定宽度
  • 您使用 SCSS / SASS (虽然可以避免)

如果是这种情况,您可以使用以下代码段:

 $itemWidth: 400px;
 $itemMargin: 10px;

html, body {
  margin: 0;
  padding: 0;
}

.flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 0 auto;
  border: solid 1px blue;
}

@for $i from 1 through 10 {
  @media only screen and (min-width: $i * $itemWidth + 2 * $i * $itemMargin) {
    .flex-container {
      width: $i * $itemWidth + 2 * $i * $itemMargin;
    }
  }
}

.item {
  flex: 0 0 $itemWidth;
  height: 100px;
  margin: $itemMargin;
  background: red;
}
<div class="flex-container">
  <div class="item"></div>
  <div class="item" style="flex: 500 0 200px"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Here我在 codepen 上创建了一个示例,它也实现了保证金。

可以分别使用css变量(如果你决定为它提供支持)和编译上面的scss片段来避免第二个和第三个条件。

嗯,这是真的,我们也可以在flexbox之前做到这一点,但display: flex对于响应式设计仍然是必不可少的。

答案 4 :(得分:0)

一个简单的技巧就增加了一个灵活的空间来填充最后一行的其余部分:

#products-list::after {
    content: "";
    flex: auto;
}

但是您不应该在项目上使用边距。而是将它们包裹在带有填充物的容器中。

Your fiddle updated

答案 5 :(得分:0)

有一个很好的解决方案,始终有效。 添加一个带有class产品的div(与flex之下的其他项相同的类)并为此div添加样式:height:0px; 您需要添加尽可能多的一次潜水。

<div class="product" style="height:0px">

可以排成一行的数目。 就这样。始终有效。

答案 6 :(得分:0)

我遇到了同样的问题,我想在一个可调整大小的容器中拥有可变数量的项目。 我想使用所有的水平空间,但所有的 flex 项目都具有相同的大小。

我最终想出了一种 javascript 方法,可以在容器调整大小时动态添加填充间隔。

    function padLastFormRow() {
        let topList = [];
        let nSpacersToAdd = 0;
        $('#flexContainer').find('.formSpacer').remove();
        $('#flexContainer').find('.formItem').each(function(i, formItem) {
            topList.push($(formItem).position().top);
        });

        let allRowLengths = getFlexLineLengths(topList);
        let firstRowLength  = allRowLengths[0];
        let lastRowLength   = allRowLengths[((allRowLengths.length) - 1)];

        if (lastRowLength < firstRowLength) {
            nSpacersToAdd = firstRowLength - lastRowLength ;
        }

        for (var i = 1; i <= nSpacersToAdd; i ++) {
            $('#flexContainer').append(formSpacerItem);
        }
    }

请看我的小提琴: http://jsfiddle.net/Harold_Buchman/z5r3ogye/11/

答案 7 :(得分:0)

我在菜单行方面遇到了类似的挑战。我想在第二行菜单项的顶部留出更多间距。

使用 flex-box 的 row-gap 效果很好。

https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap

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

这为菜单项添加了边距顶部类型效果,并被包装到第二行。