Flexbox: How to stretch row's elements to full width?

拟墨画扇 提交于 2019-12-23 17:20:01

问题


I have a flexbox grid of random width images:

I would like to stretch elements of each row to full width in order to get rid of white-space - how can I achieve that with CSS?
justify-content doesn't seem to help much. I have read about some JavaScript techniques but I would like to avoid it if possible.

[Edited] Expected result: example

.grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.grid .grid-item {
  width: auto;
  display: inline-block;
  vertical-align: bottom;
  float: none;
  margin: 1px;
  overflow: hidden;
}
.grid .grid-item .grid-in {
  padding: 0;
  width: auto;
  height: 190px;
  vertical-align: bottom;
}
.grid img {
  max-width: 100%;
  width: 100%;
  height: auto;
  padding: 0;
}
<div class="grid">
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/190x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/250x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/100x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/190x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/250x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/190x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/100x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/190x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/250x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/190x190" alt="">
    </div>
  </div>
  <div class="grid-item">
    <div class="grid-in">
      <img src="http://placehold.it/100x190" alt="">
    </div>
  </div>

</div>

回答1:


First wrap every row in an container, say .grid-row, which will have those Flexbox properties you previously assigned to .grid.

Now set flex-grow property for each cell, the value can be anything, as long as the ratio of the values per row is correct. You can simply set it to the width of the cell (without the unit), so the first cell will have flex-grow: 190. Also, make sure to set flex-shrink to 1 on all .grid-items to avoid this flexbug.

To make the images stretch all the way, remove all that inline-block business from the .grid-in. And to make them proportionally increase height, instead of being cropped to 190px, remove width: 190px from .grid-in.

Finally, to space them out, in this case it's better to use padding: 1px on .grid-item instead of margin: 1px on .grid-in.

Because the demo wasn't reduced enough, I cleaned it for the sake of clarity. Hopefully you'll know how to implement it in your original code.

.grid-row {
  display: flex;
}

.grid-item {
  flex-shrink: 1;
  padding: 1px;
}

.grid-row:nth-child(1) .grid-item:nth-child(1) { flex-grow: 190; }
.grid-row:nth-child(1) .grid-item:nth-child(2) { flex-grow: 250; }
.grid-row:nth-child(1) .grid-item:nth-child(3) { flex-grow: 100; }

.grid-row:nth-child(2) .grid-item:nth-child(1) { flex-grow: 190; }
.grid-row:nth-child(2) .grid-item:nth-child(2) { flex-grow: 250; }
.grid-row:nth-child(2) .grid-item:nth-child(3) { flex-grow: 190; }

.grid-row:nth-child(3) .grid-item:nth-child(1) { flex-grow: 100; }
.grid-row:nth-child(3) .grid-item:nth-child(2) { flex-grow: 190; }
.grid-row:nth-child(3) .grid-item:nth-child(3) { flex-grow: 250; }

.grid-row:nth-child(4) .grid-item:nth-child(1) { flex-grow: 190; }
.grid-row:nth-child(4) .grid-item:nth-child(2) { flex-grow: 100; }
.grid-row:nth-child(4) .grid-item:nth-child(3) { flex-grow: 190; }

.grid img {
  width: 100%;
  height: auto;
  vertical-align: middle;
}
<div class="grid">
  <div class="grid-row">
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/250x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/100x190" alt="">
      </div>
    </div>
  </div>
  
  <div class="grid-row">
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/250x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
  </div>
  
  <div class="grid-row">
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/100x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/250x190" alt="">
      </div>
    </div>
  </div>
  
  <div class="grid-row">
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/100x190" alt="">
      </div>
    </div>
    <div class="grid-item">
      <div class="grid-in">
        <img src="http://placehold.it/190x190" alt="">
      </div>
    </div>
  </div>
</div>



回答2:


I have stumbled across this issue and unfortunately couldn't solve it using Flexbox. The answer might suprise you, but what I found to be the appropriate solution for me here is a table, yeah you heard me right, a <table>!

There are a couple of constraints to keep in mind:

  1. You should know the numbers of cells / columns you want on each row.
  2. In the case where columns have different widths on every row, you'll need a table element for every row. ('member 2000s?)

table {
  width: 100%;
  margin: 0 0 10px 0;
  padding: 0;
  border-collapse: collapse;
}

table td {
  padding: 0;
  margin: 0;
}

img {
  display: block;
  width: 100%;
  max-width: 100%;
}
<table>
  <tr>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/250x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/100x190" alt="">
    </td>
  </tr>
</table>

<table>
  <tr>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/250x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
  </tr>
</table>

<table>
  <tr>
    <td>
      <img src="http://placehold.it/100x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/250x190" alt="">
    </td>
  </tr>
</table>

<table>
  <tr>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/100x190" alt="">
    </td>
    <td>
      <img src="http://placehold.it/190x190" alt="">
    </td>
  </tr>
</table>

You can also use other html elements and mimic the table behaviour using css
display: table | table-row | table-cell



来源:https://stackoverflow.com/questions/31671309/flexbox-how-to-stretch-rows-elements-to-full-width

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!