1

I'm trying to create a list of items in a responsive container with a consistent gap between them, including items that don't happen to have a full set of items in their row, such as this:

ul {
  width: 450px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #F00;
  justify-content: space-between;
}

li {
  display: inline-block;
  height: 100px;
  width: 100px;
  border: 1px solid #000;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Problem is the final row has a gap distance between them different than the other rows. I know I can do some quick calculations with javascript to determine the gap space, but I'd like to learn if there's a way to do this only with CSS. A left aligned list with equal gap spacing that changes as the width of the parent container changes (so if the window was a different size and the parent width was 320px, we'd only see 3 items per row, with a gap of 10px between them, including the last row containing 2, with a 110px gap to the right since there isn't a 3rd item in the row).

Rohit
  • 3,018
  • 2
  • 29
  • 58

1 Answers1

0

This strikes me as a better job for CSS grid than flexbox. Below we set display: grid to make the section display as a grid, and grid-template-columns: 1fr 1fr 1fr 1fr; to tell the grid to template four equal columns across. With this approach each new direct child in the grid will fall into each subsequent cell (as you don't tell it to explicitly do anything else) and each time four cells complete a row a new row is started. See the below snippet for an example:

ul {
  width: 450px;
  padding: 0;
  border: 1px solid #F00;
  justify-content: space-between;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

li {
  display: inline-block;
  height: 100px;
  width: 100px;
  border: 1px solid #000;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

UPDATE: I misunderstood from your initial question the manner in which you intended for your page to be "responsive". To have the grid increase the column number automatically to fill the page, you can use grid-template-columns: repeat(auto-fill, 100px). You can see this in action in the snippet below; you'll note I've changed the ul style to be 80% of the parent container-- you can grow and shrink the rendered UI in a full page snippet view to see it adjust the column number for positioning the content.

ul {
  width: 80%;
  padding: 0;
  border: 1px solid #F00;
  justify-content: space-between;
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

li {
  display: inline-block;
  height: 100px;
  width: 100px;
  border: 1px solid #000;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
  • Problem there is the responsive side, isn't it? I'd have to create breakpoints at every 100px to redefine the number of columns? I considered grid, but it seems like a lot to maintain. – Rohit Aug 29 '21 at 01:33
  • @Rohit -- I misunderstood what your responsive needs were. Your requirements can be achieved elegantly with grid-- please see the update. – Alexander Nied Aug 29 '21 at 04:05