How to align left last row/line in multiple line flexbox

CssRowFlexbox

Css Problem Overview


I have a major issue with flexbox layout. I build a container with a boxes filled with images, and i decided to use flexbox layout to justify the content to make it looks like a grid

Her's the code:

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

</div>

and the CSS:

.container {
    display: flex;
    display: -webkit-flex;
    display: -moz-flex;
    justify-content: space-around;
    -webkit-justify-content: space-around;
    -moz-justify-content: space-around;
    flex-flow: row wrap;
    -webkit-flex-flow: row wrap;
    -moz-flex-flow: row wrap;
}

.container .item { width: 130px; height: 180px; background: red; margin: 0 1% 24px; }

And everything looks good except the last line/row - when it not contain the same number of element that other lines, centering elements and it broke my grid effect.

http://jsfiddle.net/puz219/7Hq2E/

How to align last line/row to left side?

Css Solutions


Solution 1 - Css

Got it. (I think)(this is my first contribution here!)

Imagine a layout which needs to have 4 images per row. w:205 h:174 Problem: Using justify-content:space-around, if the last row doesn´t have 4 images (has 3, 2 or 1), they would not respect the grid, they would spread. So.

Create in the html 3 divs with the class "filling-empty-space-childs" like this.

.filling-empty-space-childs {
    width:205px; /*the width of the images in this example*/
    height:0; /*Important! for the divs to collapse should they fall in a new row*/
}

The flexbox container has display:flex / flex-wrap:wrap; / justify-content:space-around

The last row can have 4, 3, 2, 1 images. 4 images: no problem, this three divs would collapse in a new row since they have no height. 3 images: no problem, one div is going to be in the same row, invisible, and the other two would wrap to a new row, but will collapse since they have no height. 2 images: no problem, two divs are going to be in the same row, invisibles, the rest... collapsed 1 image: no problem, the three divs are going to fill in the space.

Solution 2 - Css

Unfortunately this is not possible with flexbox.

The best work-around is to add invisible children 'filling up' the empty 'blocks' in the last row. That way, the actual, visible, element is aligned left.

Similar question: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid

Solution 3 - Css

You can use margin-right:auto on the last-child flex item.

The problem here is that you will lose the space-between property on the left for this flex item.

Hope it helps!

Solution 4 - Css

I thought this example might be useful for anyone who wanted multiple items and allow for responsiveness, the grid items change depending on the viewport size. It does not use any invisible children, it's all done through css.

Might help someone trying align items to the left when the last row has less items and they require the page to be responsive.

http://codepen.io/kunji/pen/yNPVVb

Sample HTML

<div class="main-container">

    <div class="main-items-container">

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

        <div class="item-container">
          <h2>Item Name</h2>
        </div>

    </div>

</div>

Sample CSS

.main-container {
  max-width: 1000px;
  min-width: 300px;
  margin: 0 auto;
  padding: 40px;
  box-sizing: border-box;
  border: 1px solid #000;
}

.main-items-container {
  display: -ms-flexbox;
  display: flexbox;
  display: -webkit-flex;
  display: -ms-flex;
  display: flex;
  padding: 0;
  margin: 10px 0;
  list-style: none;
  width: auto;
  -webkit-flex-flow: row wrap;
  justify-content: flex-start;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-align-items: stretch;
  align-items: stretch;
  box-sizing: border-box;
}

@media (min-width: 971px) {
  .item-container {
    margin: 10px 2%;
    width: 22%;
    padding: 10px;
    border: 1px solid #000;
    box-sizing: border-box;
  }
  .item-container:nth-child(4n+1) {
    margin-left: 0;
  }
  .item-container:nth-child(4n) {
    margin-right: 0;
  }
}

@media (min-width: 550px) and (max-width: 970px) {
  .item-container {
    margin: 10px 2.50%;
    width: 30%;
    padding: 10px;
    border: 1px solid #000;
    box-sizing: border-box;
  }
  .item-container:nth-child(3n+1) {
    margin-left: 0;
  }
  .item-container:nth-child(3n) {
    margin-right: 0;
  }
}

@media (max-width: 549px) {
  .item-container {
    margin: 10px 0;
    width: initial;
    padding: 10px;
    border: 1px solid #000;
    box-sizing: border-box;
  }
}

Solution 5 - Css

This is not an effect you wanted to achieve?

http://jsfiddle.net/7Hq2E/21/

CSS:

.container {
    display: flex;
    display: -webkit-flex;
    display: -moz-flex;
    flex-flow: row wrap;
    -webkit-flex-flow: row wrap;
    -moz-flex-flow: row wrap;
}
.container .item {
    width: 23%;
    height: 180px;
    background: red;
    margin: 0 1% 20px;
}

HTML:

<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>

Solution 6 - Css

I've checked it and it worked better in my HTML editor tool

the script should be the way

CSS Part

> .container {
> display: flex;
> display: -webkit-flex;
> display: -moz-flex;
> justify-content: space-around;
> -webkit-justify-content: space-around;
> -moz-justify-content: space-around;
> flex-flow: row wrap;
> -webkit-flex-flow: row wrap;
> -moz-flex-flow: row wrap;
}
> > .container .item { width: 130px; height: 180px; background: green; > margin: 0 1% 24px; }

HTML Part

<div class="container">

    <div class="item"><a href='google.com'>Google</a></div>
    <div class="item"><a href='google.com'>Yahoo</a></div>
    <div class="item"><a href='google.com'>Bing</a></div>
</div>

<div class="container">
    <div class="item"><a href='google.com'>Google</a></div>
    <div class="item"><a href='google.com'>Yahoo</a></div>
    <div class="item"><a href='google.com'>Bing</a></div>

</div>


enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPuZView Question on Stackoverflow
Solution 1 - CssLa Nube - Luis R. Díaz MuñizView Answer on Stackoverflow
Solution 2 - CsssandstromView Answer on Stackoverflow
Solution 3 - CssbzinView Answer on Stackoverflow
Solution 4 - CssKunjiView Answer on Stackoverflow
Solution 5 - CssJonáš KrutilView Answer on Stackoverflow
Solution 6 - CssAhmed WildView Answer on Stackoverflow