Behaviour of last elements in grid

Viewed 296

I have got a bootstrap grid with dynamically generated images.

If the last element is alone in the row it should be centered. And if there are two elements in row, the second element should float right.

This is what I want:

Two elements in row:

A   B   D
E   F   G
H       I

One element in row:

A   B   D
E   F   G
    H    

HTML Code:

<div class="row">
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div>
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div> 
  <div class="col-md-4">
      <img src="img.jpg" />
  </div>  
</div>

This is what I get:

Two elements in row:

A   B   D
E   F   G
H   I

One element in row:

A   B   D
E   F   G
H  

I tried it with :last-child:nth-child(odd) and :last-child:nth-child(even), but in the first row the first element is odd, in the second row the first element is even, in the third row the first element is odd again and so on.

Notice that the content size variates.

4 Answers

You can use a mixture of nth-child and last-child:

.row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.col-md-6 {
  width: 33.3333%;
  height: 100px;
  border: 1px solid black;
  box-sizing: border-box;
}

.col-md-6:last-child:nth-child(3n+2) {
  /* push second child to right if last child */
  margin-left: auto;
  border-color: red;
}

.col-md-6:last-child:nth-child(3n+1) {
  /* push first child to middle if last child */
  margin: auto;
  border-color: red;
}
<div class="row">
  <div class="col-md-6">
    1
  </div>
  <div class="col-md-6">
    2
  </div>
  <div class="col-md-6">
    3
  </div>
  <div class="col-md-6">
    4
  </div>
  <div class="col-md-6">
    5
  </div>
  <div class="col-md-6">
    6
  </div>
  <div class="col-md-6">
    7
  </div>
  <div class="col-md-6">
    8
  </div>
</div><br>
<div class="row">
  <div class="col-md-6">
    1
  </div>
  <div class="col-md-6">
    2
  </div>
  <div class="col-md-6">
    3
  </div>
  <div class="col-md-6">
    4
  </div>
  <div class="col-md-6">
    5
  </div>
  <div class="col-md-6">
    6
  </div>
  <div class="col-md-6">
    7
  </div>
</div>

If you need this to work with bootstrap 3, rather than 4, then you can just use

.col-md-4:last-child:nth-child(3n+2),
.col-md-4:last-child:nth-child(3n+1){
  /* push second child to right if last child */
  margin-left: 33.333333%;
  border: 1px solid red;
}

Example bootply

You can do it using flex.

var numberOfFlexItmes = $('.flex').children('div').length;
if((numberOfFlexItmes%2) == 0){
     $('.flex').css('justify-content','space-between');
}
else{
     $('.flex').css('justify-content','space-around');
}
.flex{
  width: 300px;
  flex:1;
  display: flex;
  flex-wrap: wrap;
}
.flex-item{
  width:100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='flex'>
  <div class='flex-item'>
    A
  </div>
  <div class='flex-item'>
    B
  </div>
  <div class='flex-item'>
    C
  </div>
  <div class='flex-item'>
    D
  </div>
  <div class='flex-item'>
    E
  </div>
  <div class='flex-item'>
    F
  </div>
  <div class='flex-item'>
    G
  </div>
   <div class='flex-item'>
    H
  </div>
 
</div>

What you can do, is work out if it's got a remaining 2 or 1 when dynamically generating it and use the col-x-push-x to push it that many columns

Fiddle with two Remaining Image

<div class="container">
  <div class="row">
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4 col-md-push-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
  </div>
</div>

Fiddle with One Remaining Image

<div class="container">
  <div class="row">
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
    <div class="col-md-4 col-md-push-4">
      <img src="https://via.placeholder.com/50x50" />
    </div>
  </div>
</div>

You could approach the layout you want using flexbox.

Add justify-content: center to the row. This will center an item if it is in a row by itself.

Also target the second last item in a row. Set margin-right to auto. In a row with only two items, this will align the last item to the right.

Example:

body {
  margin: 0;
}

.row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.col {
  width: 33.3333%;
}

.col:nth-last-child(2) {
  margin-right: auto;
}

img {
  width: 100%;
  height: auto;
  display: block;
}
<div class="row">
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>

</div>
<br><br>
<div class="row">
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>
  <div class="col">
    <img src="https://unsplash.it/200x200" />
  </div>


</div>

Related