@loopmode/scss-variate

1.0.2 • Public • Published

@loopmode/scss-variate

A SCSS mixin to generate helper classes with variations of a given style.

@mixin variate($style, $sizes, $variations, $withUnits);
Argument Description
$style The name of a css style property to variate
Required. No default value
$sizes Optional. A list of size values for variations. May include units or percents (stripped for zero-values)
Default value: (0px, 5px, 10px, 20px, 40px, 80px, auto)
$variations Optional. A list of variation names that will be appended to $style with a dash
Default value: ('', 'top', 'left', 'bottom', 'right')
$withUnits Optional. Whether to additionally generate class names with concrete units
Default value: false

Usage

@import "~@loopmode/scss-variate";
variate(margin);
variate(padding);

See the output

Arguments

You can use the available arguments to customize the output.

  • Use null for the default argument value
  • Use "" for an empty argument value

Example of mixed explicit, default and empty arguments:

@include variate(margin, null, "", true);

See the output

The $style argument

Required

The base name of the style property you want to variate, e.g. margin or padding.

The $sizes argument

Default value: (0px, 5px, 10px, 20px, 40px, 80px, auto)

A list of values for which to generate class names and variations.

You can specify a custom list of sizes/values that do fit your project's needs:

$sizes: (0, 0.6rem, 1.2rem, 2.4rem, 50%, auto);
@include variate(margin, $sizes);
@include variate(padding, $sizes);

The $variations argument

Default value: ('', 'top', 'left', 'bottom', 'right')

A list of names for variations to generate. Each will be appended to the base $style name with a hyphen.

The default list contains an empty string plus all available sides, which generates typical side variations, e.g. margin, margin-top, margin-bottom, margin-left and margin-right.

However, you can also specify your own list of variations:

@include variate(margin, (0, 10px), (top));
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 10px; }
@include variate(margin, (0, 10px), (bottom, top));
.mb-0 { margin-bottom: 0; }
.mt-0 { margin-top: 0; }
.mb-1 { margin-bottom: 10px; }
.mt-1 { margin-top: 10px; }

You can also pass just an empty string to only use the base $style property and skip variations:

@include variate(margin, (0, 25px, 50px), "");
.m-0 { margin: 0; }
.m-1 { margin: 25px; }
.m-2 { margin: 50px; }

The $withUnits argument

Default value: false

Produce additional classnames that contain concrete values instead of step numbers.

@include variate(margin, null, null, true);

The default behaviour creates "step-based" class names. For example, if you create paddings for a list of values (0px, 5px, 10px), the created classnames would be .p-0, p-1, .p-2.

@include variate(margin, (0px, 5px), "");
.m-0 { margin: 0; }
.m-1 { margin: 5px; }

However, if you specify true for the last argument $withUnits, unit-based classnames will be generated additionally:

@include variate(margin, (0px, 5px), "", true);
.m-0, .m-0px { margin: 0; }
.m-1, .m-5px { margin: 5px; }

Note that if you use percentages, the % is replaced by p:

@include variate(margin, (0, 50%), "", true);
.m-0 { margin: 0; }
.m-1, .m-50p { margin: 50%; }

This is a workaround to avoid invalid syntax, as % is not allowed in class names.

Non-numerical values

If you use non-numerical $sizes like auto or none, put them to the end of your list, or you will have jumps in your steps.

Bad - the list contains auto in the middle, the step .m-1 is missing:

@include variate(margin, (0, auto, 10px), "");
.m-0 { margin: 0; }
.m-auto { margin: auto; }
.m-2 { margin: 10px; }

Good - the list contains auto at the end, the steps are correct:

@include variate(margin, (0, 10px, auto), "");
.m-0 { margin: 0; }
.m-1 { margin: 10px; }
.m-auto { margin: auto; }

Example output

The generated output for some examples.

Default

The default behavior, without any additional arguments.

@include '~@loopmode/scss-variate';
variate(margin);
variate(padding);
.m-0 { margin: 0; }
.mt-0 { margin-top: 0; }
.ml-0 { margin-left: 0; }
.mb-0 { margin-bottom: 0; }
.mr-0 { margin-right: 0; }
.m-1 { margin: 5px; }
.mt-1 { margin-top: 5px; }
.ml-1 { margin-left: 5px; }
.mb-1 { margin-bottom: 5px; }
.mr-1 { margin-right: 5px; }
.m-2 { margin: 10px; }
.mt-2 { margin-top: 10px; }
.ml-2 { margin-left: 10px; }
.mb-2 { margin-bottom: 10px; }
.mr-2 { margin-right: 10px; }
.m-3 { margin: 20px; }
.mt-3 { margin-top: 20px; }
.ml-3 { margin-left: 20px; }
.mb-3 { margin-bottom: 20px; }
.mr-3 { margin-right: 20px; }
.m-4 { margin: 40px; }
.mt-4 { margin-top: 40px; }
.ml-4 { margin-left: 40px; }
.mb-4 { margin-bottom: 40px; }
.mr-4 { margin-right: 40px; }
.m-5 { margin: 80px; }
.mt-5 { margin-top: 80px; }
.ml-5 { margin-left: 80px; }
.mb-5 { margin-bottom: 80px; }
.mr-5 { margin-right: 80px; }
.m-auto { margin: auto; }
.mt-auto { margin-top: auto; }
.ml-auto { margin-left: auto; }
.mb-auto { margin-bottom: auto; }
.mr-auto { margin-right: auto; }
.p-0 { padding: 0; }
.pt-0 { padding-top: 0; }
.pl-0 { padding-left: 0; }
.pb-0 { padding-bottom: 0; }
.pr-0 { padding-right: 0; }
.p-1 { padding: 5px; }
.pt-1 { padding-top: 5px; }
.pl-1 { padding-left: 5px; }
.pb-1 { padding-bottom: 5px; }
.pr-1 { padding-right: 5px; }
.p-2 { padding: 10px; }
.pt-2 { padding-top: 10px; }
.pl-2 { padding-left: 10px; }
.pb-2 { padding-bottom: 10px; }
.pr-2 { padding-right: 10px; }
.p-3 { padding: 20px; }
.pt-3 { padding-top: 20px; }
.pl-3 { padding-left: 20px; }
.pb-3 { padding-bottom: 20px; }
.pr-3 { padding-right: 20px; }
.p-4 { padding: 40px; }
.pt-4 { padding-top: 40px; }
.pl-4 { padding-left: 40px; }
.pb-4 { padding-bottom: 40px; }
.pr-4 { padding-right: 40px; }
.p-5 { padding: 80px; }
.pt-5 { padding-top: 80px; }
.pl-5 { padding-left: 80px; }
.pb-5 { padding-bottom: 80px; }
.pr-5 { padding-right: 80px; }
.p-auto { padding: auto; }
.pt-auto { padding-top: auto; }
.pl-auto { padding-left: auto; }
.pb-auto { padding-bottom: auto; }
.pr-auto { padding-right: auto; }

Default and empty arguments

The contrived example from above uses all default $sizes, creates no $variations and adds unit-based class names:

@include variate(margin, null, "", true);
.m-0, .m-0px { margin: 0; }
.m-1, .m-5px { margin: 5px; }
.m-2, .m-10px { margin: 10px; }
.m-3, .m-20px { margin: 20px; }
.m-4, .m-40px { margin: 40px; }
.m-5, .m-80px { margin: 80px; }
.m-auto { margin: auto; }

Bells and whistles

Notice that you could be generating a lot of CSS output, depending on your usage:

html,
body { include variate(margin, null, null, true);
  @include variate(padding, null, null, true); }
html .m-0,
html .m-0px,
body .m-0,
body .m-0px { margin: 0; }

html .mt-0,
html .mt-0px,
body .mt-0,
body .mt-0px { margin-top: 0; }

html .ml-0,
html .ml-0px,
body .ml-0,
body .ml-0px { margin-left: 0; }

html .mb-0,
html .mb-0px,
body .mb-0,
body .mb-0px { margin-bottom: 0; }

html .mr-0,
html .mr-0px,
body .mr-0,
body .mr-0px { margin-right: 0; }

html .m-1,
html .m-5px,
body .m-1,
body .m-5px { margin: 5px; }

html .mt-1,
html .mt-5px,
body .mt-1,
body .mt-5px { margin-top: 5px; }

html .ml-1,
html .ml-5px,
body .ml-1,
body .ml-5px { margin-left: 5px; }

html .mb-1,
html .mb-5px,
body .mb-1,
body .mb-5px { margin-bottom: 5px; }

html .mr-1,
html .mr-5px,
body .mr-1,
body .mr-5px { margin-right: 5px; }

html .m-2,
html .m-10px,
body .m-2,
body .m-10px { margin: 10px; }

html .mt-2,
html .mt-10px,
body .mt-2,
body .mt-10px { margin-top: 10px; }

html .ml-2,
html .ml-10px,
body .ml-2,
body .ml-10px { margin-left: 10px; }

html .mb-2,
html .mb-10px,
body .mb-2,
body .mb-10px { margin-bottom: 10px; }

html .mr-2,
html .mr-10px,
body .mr-2,
body .mr-10px { margin-right: 10px; }

html .m-3,
html .m-20px,
body .m-3,
body .m-20px { margin: 20px; }

html .mt-3,
html .mt-20px,
body .mt-3,
body .mt-20px { margin-top: 20px; }

html .ml-3,
html .ml-20px,
body .ml-3,
body .ml-20px { margin-left: 20px; }

html .mb-3,
html .mb-20px,
body .mb-3,
body .mb-20px { margin-bottom: 20px; }

html .mr-3,
html .mr-20px,
body .mr-3,
body .mr-20px { margin-right: 20px; }

html .m-4,
html .m-40px,
body .m-4,
body .m-40px { margin: 40px; }

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

html .ml-4,
html .ml-40px,
body .ml-4,
body .ml-40px { margin-left: 40px; }

html .mb-4,
html .mb-40px,
body .mb-4,
body .mb-40px { margin-bottom: 40px; }

html .mr-4,
html .mr-40px,
body .mr-4,
body .mr-40px { margin-right: 40px; }

html .m-5,
html .m-80px,
body .m-5,
body .m-80px { margin: 80px; }

html .mt-5,
html .mt-80px,
body .mt-5,
body .mt-80px { margin-top: 80px; }

html .ml-5,
html .ml-80px,
body .ml-5,
body .ml-80px { margin-left: 80px; }

html .mb-5,
html .mb-80px,
body .mb-5,
body .mb-80px { margin-bottom: 80px; }

html .mr-5,
html .mr-80px,
body .mr-5,
body .mr-80px { margin-right: 80px; }

html .m-auto,
body .m-auto { margin: auto; }

html .mt-auto,
body .mt-auto { margin-top: auto; }

html .ml-auto,
body .ml-auto { margin-left: auto; }

html .mb-auto,
body .mb-auto { margin-bottom: auto; }

html .mr-auto,
body .mr-auto { margin-right: auto; }

html .p-0,
html .p-0px,
body .p-0,
body .p-0px { padding: 0; }

html .pt-0,
html .pt-0px,
body .pt-0,
body .pt-0px { padding-top: 0; }

html .pl-0,
html .pl-0px,
body .pl-0,
body .pl-0px { padding-left: 0; }

html .pb-0,
html .pb-0px,
body .pb-0,
body .pb-0px { padding-bottom: 0; }

html .pr-0,
html .pr-0px,
body .pr-0,
body .pr-0px { padding-right: 0; }

html .p-1,
html .p-5px,
body .p-1,
body .p-5px { padding: 5px; }

html .pt-1,
html .pt-5px,
body .pt-1,
body .pt-5px { padding-top: 5px; }

html .pl-1,
html .pl-5px,
body .pl-1,
body .pl-5px { padding-left: 5px; }

html .pb-1,
html .pb-5px,
body .pb-1,
body .pb-5px { padding-bottom: 5px; }

html .pr-1,
html .pr-5px,
body .pr-1,
body .pr-5px { padding-right: 5px; }

html .p-2,
html .p-10px,
body .p-2,
body .p-10px { padding: 10px; }

html .pt-2,
html .pt-10px,
body .pt-2,
body .pt-10px { padding-top: 10px; }

html .pl-2,
html .pl-10px,
body .pl-2,
body .pl-10px { padding-left: 10px; }

html .pb-2,
html .pb-10px,
body .pb-2,
body .pb-10px { padding-bottom: 10px; }

html .pr-2,
html .pr-10px,
body .pr-2,
body .pr-10px { padding-right: 10px; }

html .p-3,
html .p-20px,
body .p-3,
body .p-20px { padding: 20px; }

html .pt-3,
html .pt-20px,
body .pt-3,
body .pt-20px { padding-top: 20px; }

html .pl-3,
html .pl-20px,
body .pl-3,
body .pl-20px { padding-left: 20px; }

html .pb-3,
html .pb-20px,
body .pb-3,
body .pb-20px { padding-bottom: 20px; }

html .pr-3,
html .pr-20px,
body .pr-3,
body .pr-20px { padding-right: 20px; }

html .p-4,
html .p-40px,
body .p-4,
body .p-40px { padding: 40px; }

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

html .pl-4,
html .pl-40px,
body .pl-4,
body .pl-40px { padding-left: 40px; }

html .pb-4,
html .pb-40px,
body .pb-4,
body .pb-40px { padding-bottom: 40px; }

html .pr-4,
html .pr-40px,
body .pr-4,
body .pr-40px { padding-right: 40px; }

html .p-5,
html .p-80px,
body .p-5,
body .p-80px { padding: 80px; }

html .pt-5,
html .pt-80px,
body .pt-5,
body .pt-80px { padding-top: 80px; }

html .pl-5,
html .pl-80px,
body .pl-5,
body .pl-80px { padding-left: 80px; }

html .pb-5,
html .pb-80px,
body .pb-5,
body .pb-80px { padding-bottom: 80px; }

html .pr-5,
html .pr-80px,
body .pr-5,
body .pr-80px { padding-right: 80px; }

html .p-auto,
body .p-auto { padding: auto; }

html .pt-auto,
body .pt-auto { padding-top: auto; }

html .pl-auto,
body .pl-auto { padding-left: auto; }

html .pb-auto,
body .pb-auto { padding-bottom: auto; }

html .pr-auto,
body .pr-auto { padding-right: auto; }

Package Sidebar

Install

npm i @loopmode/scss-variate

Weekly Downloads

7

Version

1.0.2

License

MIT

Unpacked Size

17.5 kB

Total Files

5

Last publish

Collaborators

  • loopmode