The Dead Man
The Dead Man

Reputation: 5556

Responsive flexbox with 3 items per row, then 2, then 1

I have a section which contain six items.

I want 3 items per row on desktop, and on medium device I want 2 items per row, and 1 one Item per on mobile device

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>  

Here is css:

.flex-container{
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    width: 100%;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
}

@media only screen and (max-width: 768px) and (min-width: 320px){
    .flex-container {
        display: flex;
        justify-content: center;
        flex-basis: 100%;
    }
}

This shows me only 3 items on desktop and one per item in mobile, but no 2 items, what do I need to change in my code to get what I want?

Upvotes: 4

Views: 14168

Answers (4)

agapitocandemor
agapitocandemor

Reputation: 744

Previous answers are correct, please check my answer in this very similar SO post: How to make child div fluid with respect to parent.

Also I've noted that your media query is wrong, your class is not correct, editing it.

Upvotes: 0

Michael Benjamin
Michael Benjamin

Reputation: 371003

The layout can be achieved by adjusting flex-basis inside media queries.

Here's the idea:

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

.flex-container > div {
  flex: 1 0 26%;
}

@media ( max-width: 768px) {
  .flex-container > div {
    flex-basis: 34%;
  }
}

@media ( max-width: 320px) {
  .flex-container > div {
    flex-basis: 51%;
  }
}

/* non-essential demo styles */
.flex-container > div {
  height: 50px;
  background-color: lightgreen;
  border: 2px solid white;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.2em;
}
<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

jsFiddle demo

In the first flex rule, flex-grow is set to 1. That means the flex items will consume all free space.

Hence, the width of each item, expressed through flex-basis, no longer needs to be the traditional 33.33% (3 items per row), 50% (2 per row) and 100%.

These numbers often have to be manually adjusted (e.g., calc()) to make space for margins.

In this case, thanks to flex technology, flex-grow consumes remaining space and flex-basis needs only to be large enough to enforce a wrap.

So, for example, with flex-basis: 26%, only three items can fit on the line. The fourth must wrap. There's plenty of room for margins. flex-grow fills up empty space.

Upvotes: 7

paradian
paradian

Reputation: 21

you can set the flex-basis in the <div>,i hope this may help you https://codepen.io/paradian/pen/rZQopv

Upvotes: 0

santialur
santialur

Reputation: 235

You're doing good this way with media queries.. Watch out for the 'e' in .flex-conteiner should be .flex-container

Then use media queries and flex-basis for the rest of screen sizes, for example:

@media only screen and (max-width: 768px) and (min-width: 320px){
    .flex-container {
        display: flex;
        justify-content: center;
        flex-basis: 100%;
    }
}

@media only screen and (max-width: 1200px) and (min-width: 768px){
    .flex-container {
        display: flex;
        justify-content: center;
        flex-basis: 50%;
    }
}

and for bigger screens use flex basis 33%.

Upvotes: 1

Related Questions