Stuck between flex-end and space-between and margin

Ali Sheikhpour picture Ali Sheikhpour · Sep 6, 2016 · Viewed 10.3k times · Source

In a flexbox, when I use justify-content:space-between the first and last items are exactly aligned to the bounds of flex container where space is divided between them. How can I align first item to the right where other items are also aligned to the right (not to entire the width)?

The sample code below is not good because when I use flex-end, I have to set margin for items and so the first one in each row is not sticky to the right.

and this is not also good because items are not aligned to the right (but entire the width):

#flexcontainer{
  display: -webkit-flex;
  display: flex;
  flex-wrap:wrap;
  -webkit-flex-direction: row;
  flex-direction: row;
  -webkit-justify-content: space-between;
  justify-content: space-between;
  background:#ff8800;

}


.flexitem{
	display: -webkit-flex;
	display: flex;
	margin:0;
	width:24%;
	background:#888888;
	box-sizing:border-box;
    height:50px;
}
<div id="flexcontainer">
    <div class="flexitem"></div>
    <div class="flexitem"></div>
    <div class="flexitem"></div>
  </div>

My desired output in image (first one sticks to the right with no margin-right and the 4th one sticks to the left if 4 element exist and others align to the right if more than 4): enter image description here

Answer

kukkuz picture kukkuz · Sep 7, 2016

AFAIK the best you can achieve using a flexbox to achieve your desired output can be done manipulating the flex-basis and margin of the flexitems using this:

  margin: 20px;
  display: flex;
  flex: 0 1 calc(25% - 40px);
  1. The flex-basis of calc(25% - 40px) in the flex style divides the width into four adjusting for margin also.

  2. Note I have set flex-grow disabled.

  3. flex-end finishes it up.

Let me know your feedback. Thanks!

#flexcontainer {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: flex-end;
  background: #ff8800;
}
.flexitem {
  margin: 20px;
  display: flex;
  flex: 0 1 calc(25% - 40px);
  background: #666666;
  box-sizing: border-box;
  height: 50px;
}
<div id="flexcontainer">
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
</div>

EDIT:

So I did some more adjustments to the margin calculations:

  1. Change the flex-basis by reducing 10px more to adjust for removing the 20px each at the left and right ends of a row:

    flex: 0 1 calc(25% - 30px);
    
  2. For the rightmost / leftmost boxes to sit to the right / left edge:

    .flexitem:nth-child(4n) {
      margin-right: 0;
    }
    .flexitem:nth-child(4n + 1) {
      margin-left: 0;
    }
    .flexitem:last-child {
      margin-right: 0;
    }
    

Give me your feedback on this. Thanks!

#flexcontainer {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: flex-end;
  background: #ff8800;
}
.flexitem {
  margin: 20px;
  display: flex;
  flex: 0 1 calc(25% - 30px);
  background: #666666;
  box-sizing: border-box;
  height: 50px;
}
.flexitem:nth-child(4n) {
  margin-right: 0;
}
.flexitem:nth-child(4n + 1) {
  margin-left: 0;
}
.flexitem:last-child {
  margin-right: 0;
}
<div id="flexcontainer">
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
  <div class="flexitem"></div>
</div>