I'm working with a sass file that has a looooooong set of hard-coded helper classes for padding and margins. Because we're working with scss
here, this is redundant and can be solved with a sass function or something.
The trouble I'm having is actually writing the fancy sass
to do the heavy lifting on this, because this requires... math. gasp
It currently looks like this...
// Spacing
$spacer: 1rem;
// Margin Helpers
.m-0 {margin: 0;}
.m-1 {margin: ($spacer * .25);}
.m-2 {margin: ($spacer * .5);}
.m-3 {margin: ($spacer);}
.m-4 {margin: ($spacer * 1.5);}
.m-5 {margin: ($spacer * 3);}
.mt-0 {margin-top: 0;}
.mt-1 {margin-top: ($spacer * .25);}
.mt-2 {margin-top: ($spacer * .5);}
.mt-3 {margin-top: ($spacer);}
.mt-4 {margin-top: ($spacer * 1.5);}
.mt-5 {margin-top: ($spacer * 3);}
.ml-0 {margin-left: 0;}
.ml-1 {margin-left: ($spacer * .25);}
.ml-2 {margin-left: ($spacer * .5);}
.ml-3 {margin-left: ($spacer);}
.ml-4 {margin-left: ($spacer * 1.5);}
.ml-5 {margin-left: ($spacer * 3);}
Now imagine this ^^ with every side and spacing, all hard-coded, and repeated for padding helpers. Yeah, my jaw is on the ground too.
I'd like to turn the above mess, into a sass function, mixin, whatever would be ideal for this conundrum. I've scoured the depths of the internet and have found a lot that are either more complicated than necessary, or can't do the math I need. I'm not that experienced with scss functions and mixins so don't bully me just yet.
I was experimenting for like 3 hours until I finally gave up; during which I had found and was reading a few articles that may be able to help but I couldn't wrap my noodle of a brain around it quite, so I'll include those below.
SASS Margin and Padding Helpers Loop. Generates .m-t-10 type helper classes.
How to dynamically build helper classes using SCSS
I'll give you a giant bear of a virtual hug if you can help me fix this disgrace of a sass file :)
Thanks in advance!
~ Josh
Here's a pretty simple mixin to do what you want:
@mixin generate($prefix, $property) {
// List of sizes to generate for each
$sizes: [0, .25, .5, 1, 1.5, 3];
// Spacing to multiply the sizes by
$spacing: 1rem;
// Loop through all of the sizes(we use @for rather than @each, as we want access to the index)
@for $i from 1 through length($sizes) {
// Get the size for the current index
$size: nth($sizes, $i);
// Create the rule
.#{$prefix}-#{$i - 1} {
#{$property}: $spacing * $size;
}
}
}
The usage of this mixin would look like so:
@include generate(ml, margin-left);
And would compile to:
.ml-0 {
margin-left: 0rem;
}
.ml-1 {
margin-left: 0.25rem;
}
.ml-2 {
margin-left: 0.5rem;
}
.ml-3 {
margin-left: 1rem;
}
.ml-4 {
margin-left: 1.5rem;
}
.ml-5 {
margin-left: 3rem;
}
You can play around with this sassmeister.
When it comes to generating these for a large number of properties, you could take it another step, and use an @each
:
$rules: [
[ml, margin-left],
[mt, margin-top],
[mb, margin-bottom],
[mr, margin-right],
];
@each $item in $rules {
@include generate(nth($item, 1), nth($item, 2));
}
And another sassmeister for your convenience.
While you could go deeper and just loop over the -top
, -bottom
, etc so you just have to specify a property and everything else is generated, I don't know your use case, and you can figure it out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With