Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make every row in a grid list have the same number of items (using Flexbox)? [duplicate]

I use the following CSS (with Flexbox) too achieve the grid list seen in the first image below:

display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
flex-direction: row;

The problem is that I'd like to spread out the items in the list. More specifically, I'd like every row to have the same number of items. In the case of the first image below, I'd like the MasterCard item to be moved to the second row, as seen in the second image.

It currently looks like this:

enter image description here

This how I'd like to it look:

enter image description here

Since the size of the container can change, I can't just change the margin (which I did to produce the second image).

Here is an example: (or alternatively a JS Bin with prefixes)

#container {
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
  flex-direction: row;
  display: flex;
  
  width: 450px;
  height: 130px;
  border: 1px solid #8BC34A;
  -webkit-align-self: center;
}

.item {
  justify-content: center;
  margin: 5px;
  display: inline-flex;
  width: 100px;
  height: 50px;
  background-color: #03A9F4;
}

span {
  align-self: center;
  
  color: white;
  font-family: sans-serif;
  font-size: 12px;
  
  -webkit-align-self: center;
}

body {
  display: flex;
  justify-content: center;
  flex-direction: column;
}

#title {
  display: flex;
  color: grey;
  font-family: sans-serif;
  font-size: 20px;
  margin: 10px;
}

#sub-title {
  display: flex;
  color: grey;
  font-family: sans-serif;
  font-size: 15px;
  margin-bottom: 15px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  
  <span id="title">Flexbox Grid</span>
  <span id="sub-title">How to make each row have the same number of items?</span>

  <div id="container">
    <div class="item">
      <span>ITEM #1</span>
    </div>
    <div class="item">
      <span>ITEM #2</span>
    </div>
    <div class="item">
      <span>ITEM #3</span>
    </div>
    <div class="item">
      <span>ITEM #4</span>
    </div>
    <div class="item">
     <span>ITEM #5</span>
    </div>
    <div class="item">
     <span>ITEM #6</span>
    </div>
  </div>
  
</body>
</html>

Any help would be appreciated.

JavaScript Solution

Since this question has been marked as duplicate, I have to post this answer in the question.

The JavaScript code is:

var resize = function() {
  var container = document.querySelector('#container');
  var items = document.querySelectorAll('.item');
  var css = document.querySelector('#js-css');

  var itemWidth = 100;
  var containerWidth = $(container).width();

  var perRowCount = Math.floor(containerWidth / itemWidth);
  var rowCount = Math.ceil(items.length / perRowCount);
  var newPerRowCount = Math.floor(items.length / rowCount);

  var newItemWidth = (containerWidth / newPerRowCount) - (parseInt($(items[0]).css('margin')) * 2);

  css.innerHTML = '.item { width: ' + newItemWidth + 'px; }';
};

You can run the resize() function when the viewport is resized.

Here is an example: (or alternatively a JS Bin)

var resize = function() {
  var container = document.querySelector('#container');
  var items = document.querySelectorAll('.item');
  var css = document.querySelector('#js-css');

  var itemWidth = 100;
  var containerWidth = $(container).width();

  var perRowCount = Math.floor(containerWidth / itemWidth);
  var rowCount = Math.ceil(items.length / perRowCount);
  var newPerRowCount = Math.floor(items.length / rowCount);

  var newItemWidth = (containerWidth / newPerRowCount) - (parseInt($(items[0]).css('margin')) * 2);

  css.innerHTML = '.item { width: ' + newItemWidth + 'px; }';
};

var increase = function() {
  var container = document.querySelector('#container');

  $(container).width($(container).width() + 15);

  resize();
};

var decrease = function() {
  var container = document.querySelector('#container');

  $(container).width($(container).width() - 15);

  resize();
};

resize();
#container {
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
  flex-direction: row;
  display: flex;
  -webkit-justify-content: space-around;
  -ms-justify-content: space-around;
  -webkit-align-items: center;
  -ms-align-items: center;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  display: -webkit-flex;
  display: -ms-flex;
  width: 450px;
  height: auto;
  border: 1px solid #8BC34A;
  align-self: center;
  -ms-align-self: center;
  -webkit-align-self: center;
}
.item {
  justify-content: center;
  margin: 5px;
  display: inline-flex;
  width: 100px;
  height: 50px;
  background-color: #03A9F4;
  -webkit-justify-content: center;
  -ms-justify-content: center;
  display: -webkit-inline-flex;
  display: -ms-inline-flex;
}
span {
  align-self: center;
  color: white;
  font-family: sans-serif;
  font-size: 12px;
  -webkit-align-self: center;
  -ms-align-self: center;
}
body {
  display: flex;
  justify-content: center;
  flex-direction: column;
}
#title {
  display: flex;
  color: grey;
  font-family: sans-serif;
  font-size: 20px;
  margin: 10px;
}
#sub-title {
  display: flex;
  color: grey;
  font-family: sans-serif;
  font-size: 15px;
  margin-bottom: 15px;
}
button {
  width: 100px;
  height: 40px;
  background-color: #03A9F4;
  color: white;
  align-self: center;
  margin: 10px;
}
<!DOCTYPE html>
<html>

<head>
  <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>

  <style id="js-css">
  </style>

  <span id="title">Flexbox Grid</span>
  <span id="sub-title">How to make each row have the same number of items?</span>

  <div id="container">
    <div class="item">
      <span>ITEM #1</span>
    </div>
    <div class="item">
      <span>ITEM #2</span>
    </div>
    <div class="item">
      <span>ITEM #3</span>
    </div>
    <div class="item">
      <span>ITEM #4</span>
    </div>
    <div class="item">
      <span>ITEM #5</span>
    </div>
    <div class="item">
      <span>ITEM #6</span>
    </div>
  </div>

  <button onClick="increase()">+</button>
  <button onClick="resize()">Resize Items</button>
  <button onClick="decrease()">-</button>

</body>

</html>
like image 612
davidweitzenfeld Avatar asked Nov 01 '22 11:11

davidweitzenfeld


1 Answers

#container {
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: center;
  
  min-height: 200px;
  background: #444;
}

.item {
  flex: 1 1 31%;
  
  background: #222;
  margin: 0 1%;
  height: 40px;
}

span {
  color: white; 
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>

  <div id="container">
    <div class="item">
      <span>Item #1</span>
    </div>
    <div class="item">
      <span>Item #2</span>
    </div>
    <div class="item">
      <span>Item #3</span>
    </div>
    <div class="item">
      <span>Item #4</span>
    </div>
    <div class="item">
     <span>Item #5</span>
    </div>
    <div class="item">
     <span>Item #6</span>
    </div>
    <div class="item">
     <span>Item #7</span>
    </div>
    <div class="item">
     <span>Item #8</span>
    </div>
    <div class="item">
     <span>Item #9</span>
    </div>
  </div>
  
</body>
</html>
like image 89
Alejandro B. Avatar answered Nov 12 '22 16:11

Alejandro B.