1

I am creating a responsive template using Bootstrap. I have multiple items located in a row, so that depending on a resolution there can be different amount of items in one row and a different amount of rows accordingly.

<div class="row">
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="item"> ... </div>
  </div>
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="item"> ... </div>
  </div>
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="item"> ... </div>
  </div>
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="item"> ... </div>
  </div>
  ...
</div> <!-- / .row -->

Every item has a bottom margin, so that they don't stick together vertically:

.item {
  margin-bottom: 20px;
}

Is there any way to set the bottom margin to "0" for all the items of the last row? (taken that we don't know which items will be in that last row on different resolutions).

PS: Don't get confused with the .row container. This doesn't mean that the divs inside are a single row. This is just a wrapper for the .col- containers.

JSFiddle: http://jsfiddle.net/m668fska/

amphetamachine
  • 27,620
  • 12
  • 60
  • 72
sdvnksv
  • 9,350
  • 18
  • 56
  • 108

4 Answers4

3

Add a negative margin-bottom to the row - that way all your items (including the last row) will push down, the row will pull it back.

John Ohara
  • 2,821
  • 3
  • 28
  • 54
0

Use media queries that match bootstrap's, so something like

/* Large desktop */
@media (min-width: 768px) {
    div.row>div.col-xs-6.col-sm-4.col-md-3:nth-last-child(-n+4)>div.item{
        margin-bottom:0;
    }
}

Then ditto for the following, except using nth-last-child(-n+3) and nth-last-child(-n+2) instead:

/* Landscape phone to portrait tablet */
@media (max-width: 767px) { ... }

/* Landscape phones and down */
@media (max-width: 480px) { ... }
Huey
  • 5,110
  • 6
  • 32
  • 44
  • It's ```margin-bottom``` not ```bottom-margin``` https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom – GillesC Apr 29 '15 at 11:35
  • If I understand it right, this will target the last div.col-xs-12... only. What I want is to target all the .col-xs-12.....divs that would go on the last row. – sdvnksv Apr 29 '15 at 11:44
  • Misunderstood, sorry. Fixed. – Huey Apr 29 '15 at 11:46
  • Still not a solution, because .col-* divs inside the row container can go in several rows depending on the sreen resolution, that's the problem. – sdvnksv Apr 29 '15 at 11:48
  • Ahh, I get it, so you have 4 `div.col-*` divs for the widest screen size, then 3 and 2 for smaller ones. See my updated answer then. – Huey Apr 29 '15 at 11:56
  • The answer above will work OK with a give number of items. However, if that's a picture gallery, for example, I can't know the exact number of pictures I will have to show, so I will have to edit the code every time I add a picture, which is not OK =) – sdvnksv Apr 29 '15 at 12:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76537/discussion-between-huey-and-deka87). – Huey Apr 29 '15 at 12:09
0

Technically, since you are trying to replicate a table you just need to add a style to the row;

.row {
    margin-bottom:20px;
}

then overwrite the final row of the table;

.table:last-child {
    margin-bottom:0px;
}

each .row, except the last one, will have some margin and only at the bottom.

glend
  • 1,592
  • 1
  • 17
  • 36
0

As far as I know there is no pure CSS solution …

… so here's my take on a JavaScript solution: compare each item's offset top with the last item's offset top and distribute classnames accordingly.

 // tries to adjust margin-bottom of last-row elements.
function manage_last_row_items(){

  $('.last_row_management').each(function(){
    var
      $context = $(this),
      item_selector = $context.data('item_selector'),
      $last_item = $context.find(item_selector +':last-of-type').addClass('last_row_item'),
      final_top = $last_item.offset()  ? $last_item.offset().top  : 0
    ;
    $context.find(item_selector)
      .not($last_item)
        .removeClass('last_row_item')
        .filter(function(){
          var
            o = $(this).offset(),
            decision = false
          ;
          if (o) {
            decision = o.top === final_top;
          }

          return decision;
        })
          .addClass('last_row_item')
    ;
  });  // end of ( each )
}



$(document).ready(function(){
  manage_last_row_items();
  $(window).resize(manage_last_row_items);
});

Assuming this DOM:

<ul class="last_row_management" data-item_selector="li">
…
</ul>

<form class="last_row_management" data-item_selector="fieldset">
…
</form>

Fiddle

(At this point, one could actually also take care of the last-column items …) (¬_¬ )

WoodrowShigeru
  • 1,418
  • 1
  • 18
  • 25