Tameiki
Tameiki

Reputation: 45

Flexbox - Two column in a row

I'm trying to use flexbox in order to create two columns of three row for the Products. I looked to other similar problem on StackOverflow but the answers given didn't work for me. Could you help me please ? Here the HTML code:

Informations {
  list-style-type: none;
  margin: 0;
  padding: 0;
  border: 1px solid blue;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.Information {
  border: 1px solid blue;
  margin: 0.5em;
  padding: 0.5em;
}

Game {
  list-style-type: none;
  border: 1px solid red;
  width: 100%;
  display: flex;
}

.ProductContainer {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid black;
  width: 90%;
}

.Product {
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
}

.UpgradeContainer {
  border: 1px solid black;
  width: 10%;
}

.Upgrade {
  display: flex;
  flex-flow: column wrap;
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
}
<!DOCTYPE world>
<html>

<head>
  <title> World </title>
</head>

<body>
  <Informations>
    <div class="Information">Your World:</div>
    <div class="Information">Your Money:</div>
    <div class="Information">Your ID:</div>
  </Informations>
  <Game>
    <div class="UpgradeContainer">
      <div class="Upgrade">Unlocks</div>
      <div class="Upgrade">Cash</div>
      <div class="Upgrade">Angels</div>
      <div class="Upgrade">Managers</div>
      <div class="Upgrade">Investors</div>
    </div>
    <div class="ProductContainer">
      <div class="Product">Product1</div>
      <div class="Product">Product2</div>
      <div class="Product">Product3</div>
      <div class="Product">Product4</div>
      <div class="Product">Product5</div>
      <div class="Product">Product6</div>
    </div>
  </Game>
</body>

</html>

I basically want to have to the left my upgrades (Cash, angels...) and in the middle and right two column of three row of products. Here is my code pen to see: https://codepen.io/Tameiki/pen/oNXpNVe

Upvotes: 0

Views: 183

Answers (1)

Swimmer F
Swimmer F

Reputation: 903

You can use the flex-wrap property together with setting the flex-basis on the child elements:

.ProductContainer{
  display: flex;
  flex-flow: wrap;
  border: 1px solid black;
  width: 90%;
}

.Product {
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
  flex-basis: calc(50% - 2em - 5px); /* - Margins - Borders - 1px to mitigate subpixel rounding issues*/
}
      <div class="ProductContainer">
        <div class="Product">Product1</div>
        <div class="Product">Product2</div>
        <div class="Product">Product3</div>
        <div class="Product">Product4</div>
        <div class="Product">Product5</div>
        <div class="Product">Product6</div>
      </div>


Notice how I removed the flex-direction:column property: the child elements will attempt to fit in a single row, overflowing the container if necessary.

.ProductContainer{
  display: flex;
  /*flex-flow: wrap;*/
  border: 1px solid black;
  width: 90%;
}

.Product {
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
  /*flex-basis: calc(50% - 2em - 5px); /* - Margins - Borders - 1px to mitigate subpixel rounding issues*/
}
      <div class="ProductContainer">
        <div class="Product">Product1</div>
        <div class="Product">Product2</div>
        <div class="Product">Product3</div>
        <div class="Product">Product4</div>
        <div class="Product">Product5</div>
        <div class="Product">Product6</div>
      </div>

flex-wrap is what makes them start a new line instead of overflowing:

.ProductContainer{
  display: flex;
  flex-flow: wrap;
  border: 1px solid black;
  width: 90%;
}

.Product {
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
  /*flex-basis: calc(50% - 2em - 5px); /* - Margins - Borders - 1px to mitigate subpixel rounding issues*/
}
      <div class="ProductContainer">
        <div class="Product">Product1</div>
        <div class="Product">Product2</div>
        <div class="Product">Product3</div>
        <div class="Product">Product4</div>
        <div class="Product">Product5</div>
        <div class="Product">Product6</div>
      </div>

But how do we get only two of them per row? By telling each of the child elements to be half the row's width:

.ProductContainer{
  display: flex;
  flex-flow: wrap;
  border: 1px solid black;
  width: 90%;
}

.Product {
  border: 1px solid red;
  margin: 0.5em;
  padding: 0.5em;
  flex-basis: 50%; /*calc(50% - 2em - 5px); /* - Margins - Borders - 1px to mitigate subpixel rounding issues*/
}
      <div class="ProductContainer">
        <div class="Product">Product1</div>
        <div class="Product">Product2</div>
        <div class="Product">Product3</div>
        <div class="Product">Product4</div>
        <div class="Product">Product5</div>
        <div class="Product">Product6</div>
      </div>

Unfortunately, flex-basis applies to the inner width of an element - including paddings, but excluding margins and borders. Usually, Flexbox tries to shrink child elements to fit the row if possible, but flex-wrap disables this, so we will have to adjust manually. That gets you to the code at the top.

Upvotes: 4

Related Questions