Skip to content

Instantly share code, notes, and snippets.

@jacurtis
Last active December 7, 2024 12:26
Show Gist options
  • Save jacurtis/30da4bf9a6c9b9b5cc0aebac512ca7c9 to your computer and use it in GitHub Desktop.
Save jacurtis/30da4bf9a6c9b9b5cc0aebac512ca7c9 to your computer and use it in GitHub Desktop.
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; }
@prakash321
Copy link

Thanks a lot Alex for providing this link

@mlncstr
Copy link

mlncstr 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

Exelente!

@theCrius
Copy link

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

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

Thanks <3

@LucasVilela
Copy link

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;
    }
}

@rami-sweyri
Copy link

thanks

@sergzak022
Copy link

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

@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

Thanks <3

@googoling
Copy link

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

Cool) Thx)

@caseydev
Copy link

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

its cools , i kind of like it!!!

@iqcchase
Copy link

good job!!!

@elliotrpmorris-zz
Copy link

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

@stevewinni-cc
Copy link

@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

This is wonderful, thank you

@TarasMoskovych
Copy link

$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

.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

Copy link

ghost 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);
        }
      }
  }
}

@procorbin
Copy link

procorbin commented Aug 15, 2022

A little optimization :

$spaceamounts: (0, 1, 2, 3, 4, 5, 6);
$sides: (top, bottom, left, right);

@each $space in $spaceamounts {
  @each $side in $sides {
    $parallel: if($side == top or $side == bottom, y, x);
    $unity: if($space == 0, '', em !important);
    .m#{str-slice($side, 0, 1)}-#{$space}, .m#{$parallel}-#{$space}, .m-#{$space} {
      margin-#{$side}: #{$space}#{$unity};
    }
    .p#{str-slice($side, 0, 1)}-#{$space}, .p#{$parallel}-#{$space}, .p-#{$space} {
      padding-#{$side}: #{$space}#{$unity};
    }
  }
}

@handrihmw
Copy link

$spacings: (1, 2, 3, 4, 5, auto);

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

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

@each $breakName, $breakValue in $breakpoints {
  @each $space in $spacings {
    @each $prefix, $positions in $sides {
      @if $breakName != "" {
        $prefix: #{$prefix}-#{$breakName};
      } @else {
        $prefix: #{$prefix};
      }

      @if $breakName != "" {
        @media (min-width: $breakValue) {
          .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);
            }
          }
        }
      } @else {
        .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);
          }
        }
      }
    }
  }
}

@alwaisy
Copy link

alwaisy commented Dec 28, 2022

awesome thanks, also for p-y- and m-y- m-x- p-x-

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