Search code examples
htmlcssflexboxhandlebars.jsgrid-layout

Using flexbox to position unknown number of elements in a grid with min width per element


I am looping through a bunch of objects using Express handlebars and I need to positions them in a grid. However I do not know when to make a new row so I don't think I can use a table.

I basically want a flexible number of row items with a minimum width per item. I understand flexbox can help me achieve this. I've looked up some tutorials on using it but I can't seem to find one to help me with what I need to achieve.

Here's what I have so far:

<div class="Grid">
    {{#each projects}}
        <div class="Grid-cell project">
            <img class="projectMainImage" src="/mi/{{this.mainImage}}" />
        </div>
    {{/each}}
</div>

and CSS:

.Grid {
    display: flex;
    flex-flow: row wrap;
    align-content: flex-start;
}
.Grid-cell {
    flex: 1;
    flex-grow: 1;
}
*, *:before, *:after {
    box-sizing: border-box;
}

Solution

  • You may add a min-width on the .Grid-cell element.

    Without min-width, the widest element should give the min-width of that cell (image here).

    To allow element to grow wide enough to fit its content, use the shorthand flex : flex: 1 1 auto; or flex: 1 0 auto;

    demo below

    .Grid {
      display: flex;
      flex-flow: row wrap;
      align-content: flex-start;
    }
    
    .Grid-cell {
      flex: 1 1 auto;
      min-width: 10vw;
      line-height: 10vw;
      border: solid;
      margin: 1em;
      text-align: center;
    }
    
    img {
      vertical-align: middle;
      /*eventually*/
    }
    
    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    <div class="Grid">
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/250/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
            <div class="Grid-cell project">
                <img class="projectMainImage" src="http://lorempixel.com/150/100" />
            </div>
    </div>