(Simple!) Sass/Scss margin size management

in code


Like, fuck it. After something like three years fucking with this problem, a realization has come upon me that the simplest solutions are the best solutions.

The core of my problem was this:

  1. I wanted to manage a set of margin and padding sizes from a central point.
  2. I want to base sizes all sizes off a central multiplier.
  3. I want everything to be the same type of unit.

My reason for these three requirements was to avoid the shit I came across in different codebases. Code smells such as a billion different little margins with no rhyme or reason are widespread, and these I hate with a passion.

I tried sets of variables, maps, lists, mixins and functions. I wrote elaborate mixins which only accepted certain parameters. I messed with third-party code. Variables take up too much space while returning too little-shit like margin: $m-full $m-full $-half appeared in my own code. What the fuck is $m-full?

Mixins and lists are just too fucking complex in combination, while too restrictive. Yes, it’s great there exists a master list of acceptable margin and padding sizes, but they are inflexible. A set of media query breakpoints is sensible; ten different approved margins isn’t.

Other mixins to parse sides are unwieldy as fuck-and I’m saying that as the author.

Below is my current (final) solution: The s() method takes a list of unitless numbers, maps them as multiples of $default-global-spacer, then spits out the mapped list. For example margin: m(1 3 0.5 1) with $default-global-spacer: 1.25rem becomes:

margin: 1.25rem 3.75rem 0.625rem 1.25rem

The multiplier values are themselves informative even when I don’t know $default-global-spacer, minimal logic and zero storage in lists are involved in this solution.

/**
 * Multiply a margin against the default global spacer.
 *
 * Any validations you want, you can insert here.
 *
 * @access private
 * @param {string} $margin - Margin to fetch.
 * @param {number} $spacer - Global spacer or other default value.
 * @return {number} - Happy multiplied margin.
 */

@function _m($multiplier: 1, $spacer: $default-global-spacer)
  @if $multiplier != 0 && unitless($multiplier)
    $multiplier: $spacer * $multiplier

  @return $multiplier

/**
 * Multiply list of unitless sizes.
 *
 * @access public
 * @param {string} $margin - Margin to fetch.
 * @param {number} $spacer - Global spacer or other default value.
 * @return {string} - Appropriate margin from map.
 */

@function s($sizes: (), $spacer: $default-global-spacer)
  $multiplied: ()

  @each $size in $sizes
    $multiplied: append($multiplied, _m($size, $spacer))

  @return $multiplied

Some future improvements include:

  • Bounds check the list (-1 < list < 5) (likely, reasonable-margin and padding shorthands accept 1-4 items).
  • Check against a whitelist of permitted multipliers (unlikely, unwieldy).
  • Check against a whitelist of permitted units (unlikely, unwieldy).


Remap a JavaScript Object

in code


Your email address will not be published. Required fields are marked *