Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to always have an even number of columns with auto-fill?

Hey there I am new to CSS grid. Have a look at the following example:

.platform {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  grid-gap: 20px;
}

.item {
  width:100%;
  background-color:#aaa;
  padding:10px;
  box-sizing:border-box;
  text-align:center;
}

.wrapmed {
  max-width:400px;
}

.wrapsmall {
  max-width:300px;
}
<div class="platform">
  <div class="item">a</div>
  <div class="item">b</div>
  <div class="item">c</div>
  <div class="item">d</div>
</div>

<br/><br/>

<div class="wrapmed">
  <div class="platform">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>

<br/><br/>

<div class="wrapsmall">
  <div class="platform">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>

Basically the grid works great. However I never want to break the grid such that 3 items are on top and only one item is in the next row.

I want to have either 4 columns, or two colums, or one. (How) can I achieve this behavior?

Edit: The code snippet now shows the three possible cases. Case 2 is unwanted.

like image 282
Blackbam Avatar asked Apr 30 '18 15:04

Blackbam


2 Answers

You can nest the platform divs to control how the columns will collapse.

I added a parent platform element that positions two child platform elements either side-by-side or ontop one another.
And I grouped the items in pairs or two inside of the child platform elements.

Now when the screen size shrinks, the child platform elements will stack first creating a 2x2 grid.
If the screen shrinks even more, the items inside the child platforms will stack and create a 1x4 grid.

enter image description here

.platform {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  grid-gap: 20px;
}

.item {
  width:100%;
  background-color:#aaa;
  padding:10px;
  box-sizing:border-box;
  text-align:center;
}

.wrapmed {
  max-width:400px;
}

.wrapsmall {
  max-width:300px;
}
<div class="platform">
  <div class="platform">
    <div class="item">a</div>
    <div class="item">b</div>
  </div>
  <div class="platform">
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>

<br/><br/>

<div class="wrapmed">
  <div class="platform">
    <div class="platform">
      <div class="item">a</div>
      <div class="item">b</div>
    </div>
    <div class="platform">
      <div class="item">c</div>
      <div class="item">d</div>
    </div>
  </div>
</div>

<br/><br/>

<div class="wrapsmall">
  <div class="platform">
    <div class="platform">
      <div class="item">a</div>
      <div class="item">b</div>
    </div>
    <div class="platform">
      <div class="item">c</div>
      <div class="item">d</div>
    </div>
  </div>
</div>
like image 183
Alex Wolski Avatar answered Sep 29 '22 10:09

Alex Wolski


Here's another late answer but I thought I'd record this here for future viewers with the same problem! I managed to find a solution that worked a bit better for me taking inspiration from the accepted answer, however using flexbox instead.

I used flexbox rather than CSS Grids as my requirement of this functionality was to have several cards which only collapse down in even numbers but don't go past a maximum width as this would make the cards look weird when the sub-platforms would initially collapse as their containers were too wide and the cards expanded to the width of the grid - i.e. I was restrained to the width of column grid tracks, whereas with flexbox you are not.

(If there was a way to do this with grids please comment to let me know - I tried setting the max-width of the items but then could not get them to centre within the grid cells while also growing between a minimum and maximum width of my choosing)

What I do here is use the same idea of nested containers, however they are not identical like in the accepted answer (note the additional flex property in the sub-container class). I then set my desired minimum item width using the flex-basis property in flex: 1 0 50px and my desired maximum width using max-width: 100px. Therefore I have a flex item that grows between 50-100px.

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: space-evenly;
}

.sub-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: space-around;
  flex: 1 0 50px;
}

.item {
  flex: 1 0 50px;
  max-width: 100px;
  height: 100px;
  background-color: #aaa;
  padding: 10px;
  text-align: center;
}
<div class="container">
  <div class="sub-container">
      <div class="item">a</div>
      <div class="item">b</div>
  </div>
  <div class="sub-container">
      <div class="item">c</div>
      <div class="item">d</div>
  </div>
</div>
like image 28
Lushawn Avatar answered Sep 29 '22 11:09

Lushawn