How can I align the last element of a flexbox to the right with taking into account space-around?

Viewed 110

I have a flex-div with 7 elements in it.

<div class="d-flex flex-wrap justify-content-around">
    <div style="width: 350px">
        [...]
    </div>
    [6 more identical divs]
</div>

On large screens, there are 3 divs in each row, on medium screens 2 and on small screens only 1. The last element is always centered but I want it to be aligned right. I tried margin-left: auto on the last element but due to justify-content-around there should be space on the right (first 2 rows on large screens, first 3 rows on medium screens). Unfortunately, margin-left: auto pushes the last element all the way to the right without the space from justify-content-around. How can I position the last element exactly as if it was an element of the right column?

.d-flex {
  display: flex
}

.flex-wrap {
  flex-wrap: wrap
}

.justify-content-around {
  justify-content: space-around
}

.card {
  border: 1px solid rgba(0, 0, 0, .125)
}

.ml-auto {
  margin-left: auto
}
<h3>
  Without margin-left: auto
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card" style="width: 200px">
    1
  </div>
  <div class="card" style="width: 200px">
    2
  </div>
  <div class="card" style="width: 200px">
    3
  </div>
  <div class="card" style="width: 200px">
    4
  </div>
  <div class="card" style="width: 200px">
    5
  </div>
  <div class="card" style="width: 200px">
    6
  </div>
  <div class="card" style="width: 200px">
    7 is centered
  </div>
</div>
<h3>
  With margin-left: auto
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card" style="width: 200px">
    1
  </div>
  <div class="card" style="width: 200px">
    2
  </div>
  <div class="card" style="width: 200px">
    3
  </div>
  <div class="card" style="width: 200px">
    4
  </div>
  <div class="card" style="width: 200px">
    5
  </div>
  <div class="card" style="width: 200px">
    6
  </div>
  <div class="card ml-auto" style="width: 200px">
    7 is too far to the right
  </div>
</div>

4 Answers

It goes from

1 2
3 4
5 6
7 8

For 7 to come under 6 is tricky, but lets say thats not what you meant, and just want to align the 7 to left side.

Let's start removing all these style=width, If you ever want to edit the width of div you would need to edit every single div, dumping it into the CSS is much more efficient.

<div class="card">
 4
</div>

This is the adjusted CSS

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

.justify-content-around {
  justify-content: space-between;
  display: flex;
}

.card {
  border: 1px solid rgba(0, 0, 0, 0.125);
  width: 200px;
}

If you want it aligned on the right then you can use JS but its difficult, since you use justify it might conflict.

The following solution works, if the element and the parent width are constant, i. e. you know, when there are 1 or 2 or 3 columns:

.d-flex {
  display: flex
}

.flex-wrap {
  flex-wrap: wrap
}

.justify-content-around {
  justify-content: space-around
}

.card {
  width: 200px
}

.ml-auto {
  margin-left: auto
}

.d-none {
  display: none
}

.border {
  border: 1px solid rgba(0, 0, 0, .125);
}

@media (min-width:500px) {
  .d-lg-flex {
    display: flex
  }
}

@media (min-width:700px) {
  .d-xl-flex {
    display: flex
  }
}
<h3>
  Centered
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card border">
    1
  </div>
  <div class="card border">
    2
  </div>
  <div class="card border">
    3
  </div>
  <div class="card border">
    4
  </div>
  <div class="card border">
    5
  </div>
  <div class="card border">
    6
  </div>
  <div class="card border">
    7 is centered
  </div>
</div>

<h3>
  With margin-left: auto
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card border">
    1
  </div>
  <div class="card border">
    2
  </div>
  <div class="card border">
    3
  </div>
  <div class="card border">
    4
  </div>
  <div class="card border">
    5
  </div>
  <div class="card border">
    6
  </div>
  <div class="card border ml-auto">
    7 is too far to the right
  </div>
</div>

<h3>
  Correct position
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card border">
    1
  </div>
  <div class="card border">
    2
  </div>
  <div class="card border">
    3
  </div>
  <div class="card border">
    4
  </div>
  <div class="card border">
    5
  </div>
  <div class="card border">
    6
  </div>
  <div class="card d-none d-lg-flex"></div>
  <div class="card d-none d-xl-flex"></div>
  <div class="card border">
    7 is now at correct position
  </div>
</div>

Instead of min-width:500px and min-width:700px in the media queries, use the bootstrap ones: min-width:992px and min-width:1200px. I just needed the smaller values for the snippet. Or simply use <div class="data-box d-none d-lg-flex"></div> and <div class="data-box d-none d-xl-flex"></div> for the placeholder-divs.

While other answers here are better, You should be tricky and smart,

you can create another element ,say div 8,now

  1. Change
    <div class="card" style="width: 200px">8</div> to
    <div class="space" style="width: 200px"></div>
  2. Place this div before div 7

What have we done?

  • We have removed all content inside that div(removed 8 from it)
  • We have changed class card to space, this removes the border property we apply in css(We can even remove the class instead of changing)
.card {
  border: 1px solid rgba(0, 0, 0, .125);/*removed to our element 8*/
}

Your code

  • Note: I have added just 1 line of code,in html

.d-flex {
  display: flex
}

.flex-wrap {
  flex-wrap: wrap
}

.justify-content-around {
  justify-content: space-around
}

.card {
  border: 1px solid rgba(0, 0, 0, .125)
}
<h3>
  Without margin-left: auto
</h3>
<div class="d-flex flex-wrap justify-content-around">
  <div class="card" style="width: 200px">
    1
  </div>
  <div class="card" style="width: 200px">
    2
  </div>
  <div class="card" style="width: 200px">
    3
  </div>
  <div class="card" style="width: 200px">
    4
  </div>
  <div class="card" style="width: 200px">
    5
  </div>
  <div class="card" style="width: 200px">
    6
  </div>
  <div class="space" style="width: 200px"></div><!--I HAVE ADDED ONLY THIS LINE-->
  <div class="card" style="width: 200px">
    7
  </div>
</div>

As of your original question,
"but due to justify-content-around",
You get problem when using margin-left: auto because of, justify-content- around.
The solution is to use justify-content-space-between

Snippet:

.d-flex {
  display: flex
}

.flex-wrap {
  flex-wrap: wrap
}

.justify-content-around {
  justify-content: space-between;
  margin: auto;
}

.card {
  border: 1px solid rgba(0, 0, 0, .125)
}

.card:last-child{
  margin-left: auto
}
<div class="d-flex flex-wrap justify-content-around">
  <div class="card" style="width: 200px">
    1
  </div>
  <div class="card" style="width: 200px">
    2
  </div>
  <div class="card" style="width: 200px">
    3
  </div>
  <div class="card" style="width: 200px">
    4
  </div>
  <div class="card" style="width: 200px">
    5
  </div>
  <div class="card" style="width: 200px">
    6
  </div>
  <div class="card" style="width: 200px">
    7
  </div>
</div>

Note: If you need space-around also,then use margin or fixed width,or even another parent div to make it center!

Related