Flex:包装物品的宽度与其余物品相同

时间:2017-03-13 15:38:50

标签: css css3 flexbox

我使用flex创建一个多列列表,根据容器的宽度调整列数。

我发现的问题是,如果我想通过将flex-grow设置为1来使用父级的全宽度,那么最后一个包装行中的项目是未对齐的,因为它们会尝试填充父级。

我找到了两个对我不起作用的解决方法:一个使用媒体查询,我无法使用,因为父级视口的宽度不同;另一个是使用columns,但我无法使用它,因为它会导致轮廓被切断和包裹的问题,这在我的实际设置中就已经存在。

Last two items' witdth is different

问: 有没有办法让所有项目在完整行上填充父项时具有相同的宽度?



* {
  box-sizing: border-box;
}

.wrapper {
  border: 1px solid red;
  width: 50%;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  margin: -1em -1em 0 0;
}

li {
  border: 1px solid black;
  padding: 1em;
  margin: 1em 1em 0 0;
  flex: 1 1 10em;
}

<div class="wrapper">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
    <li>Item 7</li>
    <li>Item 8</li>
  </ul>
</div>
&#13;
&#13;
&#13;

https://plnkr.co/edit/0u2QxcdLkDfhwV3zASrM

调整大小,直到最后一行有2个项目。

4 个答案:

答案 0 :(得分:6)

添加一些额外的弹性项目,并通过将其高度/填充/边框设置为0 / none使其“不可见”。 根据您需要的列数,可以减少一个列的工作量。

* {
  box-sizing: border-box;
}

.wrapper {
  border: 1px solid red;
  width: 100%;
  max-width: 800px;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;

  display: flex;
  flex-wrap: wrap;
  margin: -1em -1em 0 0;
}

li {
  border: 1px solid black;
  padding: 1em;
  margin: 1em 1em 0 0;
  flex: 1 1 10em;
}

li:nth-last-child(-n+3) {
  height: 0;
  border: none;
  padding: 0;
  margin: 0 1em 0 0;
}
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

  <body>
    <div class="wrapper">
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
        <li>Item 7</li>
        <li>Item 8</li>
        
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>
  </body>

</html>

如果所有额外元素都有内容,您也可以使用此CSS规则(感谢 Rick Hitchcock

li:empty {
  height: 0;
  border: none;
  padding: 0;
  margin: 1em 1em 0 0;
}

如果列的数量永远不会超过3,则可以使用伪元素。 (好吧,只要最后一行不会丢失超过2个项目,列就可以更多了)

* {
  box-sizing: border-box;
}

.wrapper {
  border: 1px solid red;
  width: 100%;
  max-width: 800px;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;

  display: flex;
  flex-wrap: wrap;
  margin: -1em -1em 0 0;
}

li {
  border: 1px solid black;
  padding: 1em;
  margin: 1em 1em 0 0;
  flex: 1 1 10em;
}

ul::before, ul::after {
  content: '';
  height: 0;
  border: none;
  padding: 0;
  margin: 0 1em 0 0;
  flex: 1 1 10em;
  order: 999;                /*  they need to be last  */
}
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

  <body>
    <div class="wrapper">
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
        <li>Item 7</li>
        <li>Item 8</li>        
      </ul>
    </div>
  </body>

</html>

答案 1 :(得分:1)

FLex将失败,无需填写或不填写最后一行的最终空格。

Grid,在未来将为这种行为布局提供100%的效率。

如果您启用了“实验性CSS”,则可以在FF和Chrome 下方进行测试https://igalia.github.io/css-grid-layout/enable.html

* {
  box-sizing: border-box;
}

.wrapper {
  border: 1px solid red;
  width: 50%;
  min-width:12.25em;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0 0 1em 1em;
  display: grid;
  grid-template-columns:    repeat(auto-fill, minmax(10em, 1fr))
}

li {
  border: 1px solid black;
  padding: 1em;
  margin: 1em 1em 0 0;
}
<div class="wrapper">
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
        <li>Item 7</li>
        <li>Item 8</li>
      </ul>
    </div>

当然,这不是您期望的答案,但它是关于CSS可以(将)做什么

你可以继续使用flex和一些技巧,但我相信最好的是flex +一点javascript :)。

开始学习和测试网格CSS系统,参见:

  

教程https://css-tricks.com/snippets/css/complete-guide-grid/

     

浏览器支持http://caniuse.com/#search=grid

     

polyfill https://github.com/FremyCompany/css-grid-polyfill/

     

http://gridbyexample.com/browsers/

答案 2 :(得分:0)

这取决于实际情况,但是你可以使用适当的选择器防止最后一个,两个,三个(无论我为最后两个做了哪个)孩子的flex-grow:

* {
  box-sizing: border-box;
}

.wrapper {
  border: 1px solid red;
  width: 50%;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;

  display: flex;
  flex-wrap: wrap;
  margin: -1em -1em 0 0;
}

li {
  border: 1px solid black;
  padding: 1em;
  margin: 1em 1em 0 0;
  flex: 1 1 10em;
}
li:last-child, li:nth-last-child(2) {
flex-grow: 0;
}
 
<div class="wrapper">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
    <li>Item 7</li>
    <li>Item 8</li>
  </ul>
</div>

答案 3 :(得分:0)

这就像我们需要在“ flex”规则中为商品增加一个值:一个布尔值,用于“使所有商品统一尺寸 dimension ”。像flex一样:增长 收缩 基础 统一