Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SASS Margin and Padding Helpers Loop. Generates .m-t-10 type helper classes.
/*
This .scss loop will create "margin helpers" and "padding helpers" for use in your web projects.
It will generate several classes such as:
.m-r-10 which gives margin-right 10 pixels.
.m-r-15 gives MARGIN to the RIGHT 15 pixels.
.m-t-15 gives MARGIN to the TOP 15 pixels and so on.
.p-b-5 gives PADDING to the BOTTOM of 5 pixels
.p-l-40 gives PADDING to the LEFT of 40 pixels
The first letter is "m" or "p" for MARGIN or PADDING
Second letter is "t", "b", "l", or "r" for TOP, BOTTOM, LEFT, or RIGHT
Third letter is the number of spacing in pixels. Adjust the amounts generated by editing the $spaceamounts variable below.
*/
$spaceamounts: (5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100); // Adjust this to include the pixel amounts you need.
$sides: (top, bottom, left, right); // Leave this variable alone
@each $space in $spaceamounts {
@each $side in $sides {
.m-#{str-slice($side, 0, 1)}-#{$space} {
margin-#{$side}: #{$space}px !important;
}
.p-#{str-slice($side, 0, 1)}-#{$space} {
padding-#{$side}: #{$space}px !important;
}
}
}
/*
RUN GULP to generate the classes. Now you can use these helpers to customize spacing on HTML elements.
*/
/*
THIS IS THE GENERATED FILE THAT IS PRODUCED USING THE SIMPLE LOOP SHOWN ABOVE
*/
.m-t-5 {
margin-top: 5px; }
.p-t-5 {
margin-top: 5px; }
.m-b-5 {
margin-bottom: 5px; }
.p-b-5 {
margin-bottom: 5px; }
.m-l-5 {
margin-left: 5px; }
.p-l-5 {
margin-left: 5px; }
.m-r-5 {
margin-right: 5px; }
.p-r-5 {
margin-right: 5px; }
.m-t-10 {
margin-top: 10px; }
.p-t-10 {
margin-top: 10px; }
.m-b-10 {
margin-bottom: 10px; }
.p-b-10 {
margin-bottom: 10px; }
.m-l-10 {
margin-left: 10px; }
.p-l-10 {
margin-left: 10px; }
.m-r-10 {
margin-right: 10px; }
.p-r-10 {
margin-right: 10px; }
.m-t-15 {
margin-top: 15px; }
.p-t-15 {
margin-top: 15px; }
.m-b-15 {
margin-bottom: 15px; }
.p-b-15 {
margin-bottom: 15px; }
.m-l-15 {
margin-left: 15px; }
.p-l-15 {
margin-left: 15px; }
.m-r-15 {
margin-right: 15px; }
.p-r-15 {
margin-right: 15px; }
.m-t-20 {
margin-top: 20px; }
.p-t-20 {
margin-top: 20px; }
.m-b-20 {
margin-bottom: 20px; }
.p-b-20 {
margin-bottom: 20px; }
.m-l-20 {
margin-left: 20px; }
.p-l-20 {
margin-left: 20px; }
.m-r-20 {
margin-right: 20px; }
.p-r-20 {
margin-right: 20px; }
.m-t-25 {
margin-top: 25px; }
.p-t-25 {
margin-top: 25px; }
.m-b-25 {
margin-bottom: 25px; }
.p-b-25 {
margin-bottom: 25px; }
.m-l-25 {
margin-left: 25px; }
.p-l-25 {
margin-left: 25px; }
.m-r-25 {
margin-right: 25px; }
.p-r-25 {
margin-right: 25px; }
.m-t-30 {
margin-top: 30px; }
.p-t-30 {
margin-top: 30px; }
.m-b-30 {
margin-bottom: 30px; }
.p-b-30 {
margin-bottom: 30px; }
.m-l-30 {
margin-left: 30px; }
.p-l-30 {
margin-left: 30px; }
.m-r-30 {
margin-right: 30px; }
.p-r-30 {
margin-right: 30px; }
.m-t-35 {
margin-top: 35px; }
.p-t-35 {
margin-top: 35px; }
.m-b-35 {
margin-bottom: 35px; }
.p-b-35 {
margin-bottom: 35px; }
.m-l-35 {
margin-left: 35px; }
.p-l-35 {
margin-left: 35px; }
.m-r-35 {
margin-right: 35px; }
.p-r-35 {
margin-right: 35px; }
.m-t-40 {
margin-top: 40px; }
.p-t-40 {
margin-top: 40px; }
.m-b-40 {
margin-bottom: 40px; }
.p-b-40 {
margin-bottom: 40px; }
.m-l-40 {
margin-left: 40px; }
.p-l-40 {
margin-left: 40px; }
.m-r-40 {
margin-right: 40px; }
.p-r-40 {
margin-right: 40px; }
.m-t-45 {
margin-top: 45px; }
.p-t-45 {
margin-top: 45px; }
.m-b-45 {
margin-bottom: 45px; }
.p-b-45 {
margin-bottom: 45px; }
.m-l-45 {
margin-left: 45px; }
.p-l-45 {
margin-left: 45px; }
.m-r-45 {
margin-right: 45px; }
.p-r-45 {
margin-right: 45px; }
.m-t-50 {
margin-top: 50px; }
.p-t-50 {
margin-top: 50px; }
.m-b-50 {
margin-bottom: 50px; }
.p-b-50 {
margin-bottom: 50px; }
.m-l-50 {
margin-left: 50px; }
.p-l-50 {
margin-left: 50px; }
.m-r-50 {
margin-right: 50px; }
.p-r-50 {
margin-right: 50px; }
@suyash01
Copy link

suyash01 commented Jul 27, 2017

Thanks Alex, the sass is fine but the output css you provided has all margins instead of padding.

@chitru
Copy link

chitru commented Aug 31, 2017

Thank yo so much.. !!

@tuffs
Copy link

tuffs commented Sep 15, 2017

Nice gist. Very appreciative Alex! This will save me lots of time and cash!

@prakash321
Copy link

prakash321 commented Nov 18, 2017

Thanks a lot Alex for providing this link

@markmakes
Copy link

markmakes commented Jan 5, 2018

Beautiful stuff. Now an all margin and padding one...

$spaceamounts: (5, 10, 15, 20, 25, 30);
$sides: (top, bottom, left, right, all);

@each $space in $spaceamounts {
  @each $side in $sides {

    @if $side == 'all' {
      .m#{$space} {
        margin: #{$space}px;
      }

      .p#{$space} {
        padding: #{$space}px;
      }
    } @else {
      .m#{str-slice($side, 0, 1)}#{$space} {
        margin-#{$side}: #{$space}px;
      }

      .p#{str-slice($side, 0, 1)}#{$space} {
        padding-#{$side}: #{$space}px;
      }
    }
  }
}

@tuversiondigital
Copy link

tuversiondigital commented Jan 9, 2018

Exelente!

@theCrius
Copy link

theCrius commented Jan 26, 2018

I keep getting this error and don't know why. Any hint?

ERROR in ./~/css-loader!./~/sass-loader/lib/loader.js!./~/postcss-loader!./src/index.scss
Module build failed: Unknown word (22:11)

  20 |
  21 |     @if $side == '' {
> 22 |       .m#{$space} {
     |           ^
  23 |         margin: #{$space}px;
  24 |       }

I'm using webpack 2.2.1 (from yeoman-fountain-js). Could it be an issue with the loader?

@edthenet
Copy link

edthenet commented Mar 7, 2018

if you also use a 0 (zero) in spaceammounts you also have the possibility to have no margin or padding

@hellraiserrob
Copy link

hellraiserrob commented Mar 23, 2018

Optional adjustment

$spaceamounts: (0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100);
$sides: (
  "": "all",
  "t": "top",
  "b": "bottom",
  "l": "left",
  "r": "right",
);

@each $space in $spaceamounts {
  @each $prefix, $value in $sides {
    $property: if($prefix == '', '', -#{$value});
    .m#{$prefix}#{$space} {
      margin#{$property}: #{$space}px;
    }
    .p#{$prefix}#{$space} {
      padding#{$property}: #{$space}px;
    }
  }
}

@klimo-v
Copy link

klimo-v commented Apr 15, 2018

Thanks!

@Agressiva86
Copy link

Agressiva86 commented May 16, 2018

Thanks <3

@LucasVilela
Copy link

LucasVilela commented May 17, 2018

To include m-10 p-10

$spaceamounts: (0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100); // Adjust this to include the pixel amounts you need.
$sides: (top, bottom, left, right); // Leave this variable alone
@each $space in $spaceamounts {
    @each $side in $sides {
        .m#{str-slice($side, 0, 1)}-#{$space} {
            margin-#{$side}: #{$space}px !important;
        }
        .p#{str-slice($side, 0, 1)}-#{$space} {
            padding-#{$side}: #{$space}px !important;
        }
    }
}

@each $space in $spaceamounts {
    .m-#{$space} {
        margin: #{$space}px !important;
    }
    .p-#{$space} {
        padding: #{$space}px !important;
    }
}

@ramiasg
Copy link

ramiasg commented May 22, 2018

thanks

@sergzak022
Copy link

sergzak022 commented Jun 8, 2018

Thank you very much for that!

@GCobo
Copy link

GCobo commented Jun 22, 2018

how includes a media queries inside the function?

@hrubysi
Copy link

hrubysi commented Jul 3, 2018

You could include a media queries like this:

$sides: (
"": "",
"t": "top",
"b": "bottom",
"l": "left",
"r": "right",
);

$breakpoints: (
"": "",
"xs": 576px,
"sm": 768pxm,
"md": 992px,
"lg": 1200px,
);

@each $breakName, $breakValue in $breakpoints {
  @each $sideName, $sideValue in $sides {
    @for $i from 0 through 10 {
      
      $property: if($sideName == '', '', -#{$sideValue});
      $space: $i * 10;
      $selector: '';

      @if $breakName != "" {
        $selector: #{$sideName}-#{$breakName}-#{$i};
      } @else {
        $selector: #{$sideName}-#{$i};
      }

      @if $breakName != "" {
        @media (min-width: $breakValue) {
          .m#{$selector} {
            margin#{$property}: #{$space}px;
          }
  
          .p#{$selector} {
            padding#{$property}: #{$space}px;
          }
        }
      } @else {
        .m#{$selector} {
          margin#{$property}: #{$space}px;
        }

        .p#{$selector} {
          padding#{$property}: #{$space}px;
        }
      }
    }
  }
}

Generates

.mt-4 {
  margin-top: 40px; }

.pt-4 {
  padding-top: 40px; }

@media (min-width: 576px) {
  .mt-xs-4 {
    margin-top: 40px; }

  .pt-xs-4 {
    padding-top: 40px; } }

etc...

@stephencostello
Copy link

stephencostello commented Jul 6, 2018

@hrubysi is it possible to run the loop inside the media query? for example...

@media screen and (min-width: 63.9375em) {
.large-pt0{padding-top:0!important}
.large-pb1{padding-bottom:1rem!important}
.large-pl2{padding-left:2rem!important}
.large-pr3{padding-right:3rem!important}
....
}

@Elvenmagic
Copy link

Elvenmagic commented Oct 8, 2018

Thanks <3

@googoling
Copy link

googoling commented Dec 8, 2018

You could include a media queries like this:

$sides: (
"": "",
"t": "top",
"b": "bottom",
"l": "left",
"r": "right",
);

$breakpoints: (
"": "",
"xs": 576px,
"sm": 768pxm,
"md": 992px,
"lg": 1200px,
);

@each $breakName, $breakValue in $breakpoints {
  @each $sideName, $sideValue in $sides {
    @for $i from 0 through 10 {
      
      $property: if($sideName == '', '', -#{$sideValue});
      $space: $i * 10;
      $selector: '';

      @if $breakName != "" {
        $selector: #{$sideName}-#{$breakName}-#{$i};
      } @else {
        $selector: #{$sideName}-#{$i};
      }

      @if $breakName != "" {
        @media (min-width: $breakValue) {
          .m#{$selector} {
            margin#{$property}: #{$space}px;
          }
  
          .p#{$selector} {
            padding#{$property}: #{$space}px;
          }
        }
      } @else {
        .m#{$selector} {
          margin#{$property}: #{$space}px;
        }

        .p#{$selector} {
          padding#{$property}: #{$space}px;
        }
      }
    }
  }
}

Generates

.mt-4 {
  margin-top: 40px; }

.pt-4 {
  padding-top: 40px; }

@media (min-width: 576px) {
  .mt-xs-4 {
    margin-top: 40px; }

  .pt-xs-4 {
    padding-top: 40px; } }

etc...

hi,
Can you please create another loop like: py-1, px-1, where compiled css will be like padding-right:10px; padding-left:10px; padding-top-:10px; padding-bottom:10px;

@DenisKondrachukYi
Copy link

DenisKondrachukYi commented Dec 24, 2018

Cool) Thx)

@caseydev
Copy link

caseydev commented Feb 19, 2019

spaceamounts

I want to loop for spaceamounts too. like 1,2,3,4, and so on instead of set fix value like (5,10,20,50)

@iqcchase
Copy link

iqcchase commented Feb 22, 2019

its cools , i kind of like it!!!

@iqcchase
Copy link

iqcchase commented Feb 22, 2019

good job!!!

@elliotrpmorris-zz
Copy link

elliotrpmorris-zz commented Mar 8, 2019

Is there a way to do this using rems rather than pxs ?

@stevewinni-cc
Copy link

stevewinni-cc commented Mar 27, 2019

@elliotrpmorris, I run it like this;

$spaceamounts: (0, 1, 2, 3, 4, 5, 6, 7); // Adjust this to include the pixel amounts you need.
$sides: (top, bottom, left, right); // Leave this variable alone

@include media-breakpoint-up(md) {
  @each $space in $spaceamounts {
    @each $side in $sides {
      .m#{str-slice($side, 0, 1)}-#{$space} {
          margin-#{$side}: #{$space}rem !important;
      }
    
      .p#{str-slice($side, 0, 1)}-#{$space} {
        padding-#{$side}: #{$space}rem !important;
      }
    }
  }
}

And I'm adding a breakpoint size modifier using a scale basis;

$scale-xs: 0.75;
$scale-sm: 0.8;
$scale-md: 0.85;
$scale-lg: 0.9;
$scale-xl: 0.95;

@gerardvcruz
Copy link

gerardvcruz commented May 11, 2020

This is wonderful, thank you

@TarasMoskovych
Copy link

TarasMoskovych commented Jun 29, 2020

$spaceamounts: (2, 5, 8, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100);
$sides: (all, x, y, top, bottom, left, right);

@mixin make-space($prefix, $property) {
  $property-prefix: #{str-slice($property, 0, 1)};

  @each $space in $spaceamounts {
    @each $side in $sides {

      @if $side == 'all' {
        .#{$prefix}-#{$property-prefix}-#{$space} {
          #{$property}: #{$space}px !important;
        }
      } @else if $side == 'x' or $side == 'y' {
        .#{$prefix}-#{$property-prefix}#{$side}-#{$space} {

          @if $side == 'x' {
            #{$property}-left: #{$space}px !important;
            #{$property}-right: #{$space}px !important;
          } @else {
            #{$property}-top: #{$space}px !important;
            #{$property}-bottom: #{$space}px !important;
          }
        }
      } @else {
        .#{$prefix}-#{$property-prefix}#{str-slice($side, 0, 1)}-#{$space} {
          #{$property}-#{$side}: #{$space}px !important;
        }
      }
    }
  }
}

@media (min-width: 1px) {
  @include make-space(xs, margin);
  @include make-space(xs, padding);
}

@media (min-width: 768px) {
  @include make-space(md, margin);
  @include make-space(md, padding);
}

@bhadresharya
Copy link

bhadresharya commented Sep 11, 2020

.m-t-5 {
  margin-top: 5px; }

.p-t-5 {
  margin-top: 5px; }

.m-b-5 {
  margin-bottom: 5px; }

.p-b-5 {
  margin-bottom: 5px; }

It's just margin in all css classes. even in padding class too

@chaserda
Copy link

chaserda commented Mar 22, 2021

Just want to throw my solution in. This will take care of x / y axis and all sides. However it does not include breakpoints.

@use './variables'; <--- This would be your variable file or you can hard code values in $spacing-values below

$spacing-values: (
  "25": variables.$spacing-25,
  "50": variables.$spacing-50,
  "75": variables.$spacing-75,
  "100": variables.$spacing-100,
  "200": variables.$spacing-200,
  "300": variables.$spacing-300,
  "400": variables.$spacing-400,
  "500": variables.$spacing-500,
  "600": variables.$spacing-600,
  "700": variables.$spacing-700,
  "800": variables.$spacing-800,
  "900": variables.$spacing-900,
  "1000": variables.$spacing-1000,
  "1100": variables.$spacing-1100,
  "1200": variables.$spacing-1200,
  "1300": variables.$spacing-1300,
  "1400": variables.$spacing-1400,
);

$spacing-modifiers: (
  "ma": margin,
  "mx": margin,
  "my": margin,
  "mt": margin-top,
  "mr": margin-right,
  "mb": margin-bottom,
  "ml": margin-left,
  "pa": padding,
  "px": padding,
  "py": padding,
  "pt": padding-top,
  "pr": padding-right,
  "pb": padding-bottom,
  "pl": padding-left,
);

@mixin create-spacing-classes($modifier, $value) {
  @each $number, $val in $spacing-values {
    @if ($modifier == "mx" or $modifier == "px") {
      .#{$modifier}-#{$number} {
        #{$value}: 0 $val;
      }
    } @else if ($modifier == "my" or $modifier == "py") {
      .#{$modifier}-#{$number} {
        #{$value}: $val 0;
      }
    } @else {
      .#{$modifier}-#{$number} {
        #{$value}: $val;
      }
    }
  }
}

@each $modifier, $value in $spacing-modifiers {
  @include create-spacing-classes($modifier, $value);
}

@symplytheo
Copy link

symplytheo commented Mar 2, 2022

Just dropping this for anyone who gets here:

  • it handles all sides
$spacings: (1,2,3,4,5,auto);

$sides: (
  't': 'top',
  'b': 'bottom',
  'l': 'left',
  'r': 'right',
  'a': ('top', 'left', 'bottom', 'right'),
  'x': ('left', 'right'),
  'y': ('top', 'bottom'),
);

@each $space in $spacings {
    @each $prefix, $positions in $sides {
      .p#{$prefix}-#{$space} {
        @each $pos in $positions {
            padding-#{$pos}: if($space == auto, $space, #{$space * 0.25}rem);
        }
      }
      .m#{$prefix}-#{$space} {
        @each $pos in $positions {
            margin-#{$pos}: if($space == auto, $space, #{$space * 0.25}rem);
        }
      }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment