20

I have a row with X possible columns.

<div class="container">
    <div class="row">
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <div class="col-lg-3 col-sm-4 col-xs-6">content</div>
        <!-- ... and so on ... -->
    </div>
</div>

Now I would like to add margin-top:20px to all small screen columns and the same margin for big screen columns, if there are more than 4 as that would cause two "rows" to be shown and would therefore require some space between.

Is that somehow possible with only the use of CSS?

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
n00b
  • 16,088
  • 21
  • 56
  • 72

5 Answers5

33

You can use a media query for whenever you want the top margin..

@media (max-width: 767px) {
    .col-xs-6 {
        margin-top:20px;
    }
}

http://www.bootply.com/126007

P.S. - There is nothing wrong with having the total of .col-* in a .row exceeding 12 (ie: http://getbootstrap.com/css/#grid-example-mixed). It simply causes a wrap. There are several examples in the docs that use this technique. It's generally not ideal for nested rows.

Anders Lindén
  • 6,839
  • 11
  • 56
  • 109
Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
  • 1
    Shouldn't the media query be "max-width: 767px", since Bootstrap 3's .col-sm applies to "≥768px"? – Marcos Pereira Aug 01 '15 at 22:55
  • 1
    Am I the only one who thinks that there should be a better solution (a margin class http://stackoverflow.com/a/20096216/2219831 ) probably. In order to add vertical space between items, the **content editor** will have to edit CSS. Also there could be a scenario where not all stacked elements would need vertical spacing. – Ejaz Aug 09 '16 at 13:29
  • Ya, the margin class would work too, and there is something like this in the upcoming Bootstrap 4. However, the margin class does'nt work for a specific grid tier/breakpoint like this solution. Generally content is contained within another element (ie:

    ) which would also provide spacing.

    – Carol Skelly Aug 09 '16 at 14:20
7

I needed something similar and following is the solution I came up with. Documenting it for future readers (and myself)

$res-list: (xs: (0px, 767px), sm: (768px, 991px), md: (992px, 1199px), lg: (1200px, 9999px));
$dir-list: (t: top, r: right, b: bottom, l: left);

@for $r from 1 through 10{
  @each $res-abbr, $res-vals in $res-list{
    @media (min-width: nth($res-vals, 1)) and (max-width: nth($res-vals, 2)) {
      @each $dir-abbr, $dir-name in $dir-list{
        $x: $r * 5;
        .m#{$dir-abbr}-#{$res-abbr}-#{$x}{
          margin-#{$dir-name}: #{$x}px;
        }
        .m#{$dir-abbr}-#{$res-abbr}-#{$r}p{
          margin-#{$dir-name}: #{$r}unquote('%');
        }
      }
    }
  }
}

This SASS code generates classes along the lines of following

@media (min-width: 0px) and (max-width: 767px) {
    .mt-xs-5 { margin-top: 5px; }
    .mt-xs-1p { margin-top: 1%; }
    .mr-xs-5 { margin-right: 5px; }
    .mr-xs-1p { margin-right: 1%; }
    .mb-xs-5 { margin-bottom: 5px; }
    .mb-xs-1p { margin-bottom: 1%; }
    .ml-xs-5 { margin-left: 5px; }
    .ml-xs-1p { margin-left: 1%; } 
}

So the content editor can use .mt-xs-10 to apply margin-top: 10px to given element on extra-small screen.

I hope it helps somebody.

Ejaz
  • 8,719
  • 3
  • 34
  • 49
  • 3
    You should be congratulated for massively over-complicating a simple task. – Relaxing In Cyprus Sep 26 '17 at 10:21
  • 3
    I would not think it as being over-complicated but being empowering to the content editors. Think about the usage of resulting CSS rules. – Ejaz May 08 '18 at 14:59
  • Interesting ressource, for small projects it is overcomplicating thinks but for larger ones(repeated simple tasks) it is smarter and more simple. – Aness Sep 19 '19 at 09:38
3

This is an old post but below is a clean solution.

[class*="col-"] {
  margin-bottom: 15px;
}

This works well for some situations but it adds extra, unnecessary margin when it's not needed. To solve this, we can create a new css class that applies top margin to columns when they get stacked. I create a class named .row-grid

.row.row-grid [class*="col-"] + [class*="col-"] {
  margin-top: 15px;
}

@media (min-width: 1200px) {
  .row.row-grid [class*="col-lg-"] + [class*="col-lg-"] {
    margin-top: 0;
  }
}
@media (min-width: 992px) {
  .row.row-grid [class*="col-md-"] + [class*="col-md-"] {
    margin-top: 0;
  }
}
@media (min-width: 768px) {
  .row.row-grid [class*="col-sm-"] + [class*="col-sm-"] {
    margin-top: 0;
  }
}
1

I use this simple and clean solution:

.row { margin-top: -15px; }
.row > div { margin-top: 15px; }

In that manner, every <div class='col-*-*'> has 15px margin on top, except those on the first row (or, on mobile, except the one on the top).

Marco Panichi
  • 1,068
  • 1
  • 18
  • 31
1

This simple solution automatically applies a top margin to all columns except the first, at extra small screen sizes. No special class names or other modifications to HTML or CSS are necessary. (Change the margin-top value below to whatever you prefer.)

@media (max-width: 767px) {
  [class*="col-"]:not(:first-child) {
    margin-top: 30px;
  }
}
komlenic
  • 99
  • 1
  • 3