Jamie Jamier
Jamie Jamier

Reputation: 539

Flexbox dynamic layout

I am coding a layout that I managed to achieve it by Grid but I don't know how can I do it in FlexBox. The reason I want to do it in FlexBox is because IE-11 does not support Grid properly.

To make it simpler lets only think about xs screens and I the fact that I have 6 cards:

<div class="container" >
  <div class="card1" > card 1 </div>
  <div class="card2" > card 2 </div>
  <div class="card3" > card 3 </div>
  <div class="card4" > card 4 </div>
  <div class="card5" > card 5 </div>
  <div class="card6" > card 6 </div>
</div>

I would like to have such a structure so I can add and remove cards dynamically and layout automatically changes based on the number of cards within it.

The default size of the card is always to it's container width which means if I have one card it will be full width.

<div class="container" >
  <div class="card1" > card 1 </div>
</div>

if I have two card the width will be divided between them: Kind of like flex-grow

<div class="container" >
  <div class="card1" > card 1 </div>
  <div class="card2" > card 2 </div>
</div>

The problem with flex-grow is I cannot control how they get stacked. if you think about the 6 card problem in a xs screen I want them to be stacked in 3 row of 2 card each and I cannot break them with flex-grow

So if I go to medium screen size I want them to be in 2 row of 3 cards and xs screen => 3 row, 2 cards

I know that flex is one directional but hope there are tricks and tips that I haven't heard. I have a codepen example here at https://codepen.io/jamie-jamier/pen/yLewWqy but it is not quite what I like, If you resize the screen to 500px you can see with flex-wrap it becomes 1 card per row

Upvotes: 0

Views: 1142

Answers (2)

Parth
Parth

Reputation: 151

As per my understanding of your requirements, I have modified your CSS a bit and added a media query for medium size screen. See if it fits your requirements.

.container {
  display: flex;
}

.card {
  flex: 1;
  height: 300px; 
}

.card1 { background-color: lemonchiffon; }
.card2 { background-color: lightblue; }
.card3 { background-color: mediumspringgreen; }
.card4 { background-color: khaki; }
.card5 { background-color: orchid; }
.card6 { background-color: darkgray; }

/* Medium devices */
@media only screen and (max-width: 1000px) {
  .container {
    flex-wrap: wrap;
  }
  .card {
    flex: 1 1 33.33%;
  } 
}

/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {
  .card {
    flex: 1 1 50%;
  } 
}
<div class="container">
  <div class="card card1"> card 1 </div>
  <div class="card card2"> card 2 </div>
  <div class="card card3"> card 3 </div>
  <div class="card card4"> card 4 </div>
  <div class="card card5"> card 5 </div>
  <div class="card card6"> card 6 </div>
</div>

Upvotes: 2

Francisco Espinoza
Francisco Espinoza

Reputation: 11

until this time, i can't think on this whitout some js, something to count the elements and apply differents styles, something like this:

var cards = $('.card').length;

if(cards <= 1){
  $('.card').addClass('justOne');
}else if(cards <=2){
  $('.card').addClass('twoCards');
}else{
  $('.card').addClass('moreThanTree');
}
.card { 
  height: 300px;
}

.justOne{
  width: 100%;
}

.twoCards{
  width: 50%
}

.moreThanTree{
  width: 33.333%;
}

.card1 { background-color: lemonchiffon; }
.card2 { background-color: lightblue; }
.card3 { background-color: mediumspringgreen; }
.card4 { background-color: khaki; }
.card5 { background-color: orchid; }
.card6 { background-color: darkgray; }


.container {
  display: flex;
  flex-flow: wrap
}

/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {
  .container {
    flex-wrap: wrap;
  }

  .card {
    background-color: blue;
  } 
}
<div class="container" >
  <div class="card card1" > card 1 </div>
  <div class="card card2" > card 2 </div>
  <div class="card card3" > card 3 </div>
  <div class="card card4" > card 4 </div>
  <div class="card card5" > card 5 </div>
  <div class="card card6" > card 6 </div>
  <div class="card card5" > card 7 </div>
  <div class="card card6" > card 8 </div>
</div>

Check this pen based on yours(using jQuery):

https://codepen.io/francisco2016/pen/bGEZyQJ

Upvotes: 1

Related Questions