knitevision knitevision - 6 months ago 35
CSS Question

How to control number of items per row using media queries in Flexbox?

So imagine I have the following Markup

<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>


And the following styles (SASS)

@mixin max-width($width) {
@media screen and (max-width: $width) {
@content;
}
}

.container {
display: flex;

@include max-width(992px) {
number: 4; //Hypothetical property that is supposed to control number per row
}

@include max-width(640px) {
number: 2; //Hypothetical property that is supposed to control number per row
}
}
.item {
background-color: tomato;
padding: 20px;
margin-right: 20px;
flex: 1;
}


Is there a real Flexbox CSS alternative to my hypothetical
number
property that can control how many items to show per row ?

The float-like grid was handy because you could fit unlimited
.items
per one
.row
because of the
width
. But with flexbox I have to use workarounds like numerous
.row
classes to control the layout and number of items at different width. I've been lucky so far, but there are certain type of layout which will fail with such an approach.

Codepen link to demonstrate

Answer Source

I had to get rid of the margin around the blocks, because percentage widths are difficult to cleanly apply to elements with margins, but you can see the changes at http://codepen.io/anon/pen/jPeLYb?editors=110 :

@mixin max-width($width) {
    @media screen and (max-width: $width) {
        @content;
    }
}

.container {
    position: relative;
    display: flex;
    flex-flow: row wrap;
}
.item {
    background-color: tomato;
    box-sizing: border-box;
    padding: 20px;
    outline: 2px solid blue;
    flex: 1;
}

@include max-width(992px) {
    .item {
        flex-basis: 25%;
        background-color: red;
    }
}

@include max-width(640px) {
    .item {
        flex-basis: 50%;
        background-color: green;
    }
}

The important parts here are:

  • flex-flow: row wrap which allows the flexbox to appear on multiple rows (the default is nowrap)

  • flex-basis which is the equivalent of width in this case

  • position: relative which makes the widths relative to the container, rather than the body (this would screw up the rounding)