Skip to content

Instantly share code, notes, and snippets.

@sarahdayan
Last active October 31, 2023 18:28
Show Gist options
  • Star 86 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save sarahdayan/4d2cc04a636e8039f10a889a0e29fbd9 to your computer and use it in GitHub Desktop.
Save sarahdayan/4d2cc04a636e8039f10a889a0e29fbd9 to your computer and use it in GitHub Desktop.
Sass Modifiers Mixin
// ----
// Sass (v3.4.21)
// Compass (v1.0.3)
// ----
// Sass modifiers mixin by Sarah Dayan
// Generate All Your Utility Classes with Sass Maps: frontstuff.io/generate-all-your-utility-classes-with-sass-maps
// http://frontstuff.io
// https://github.com/sarahdayan
$colors: (
red: #ff3538,
grey: (
base: #404145,
light: #c7c7cd
),
yellow: (
base: #ecaf2d
),
green: (
base: #5ad864
)
);
$font-sizes: (
small: 12px,
medium: 14px,
large: 16px,
x-large: 18px,
xx-large: 20px
);
@mixin modifiers($map, $attribute, $prefix: '-', $separator: '-', $base: 'base') {
@each $key, $value in $map {
&#{if($key != $base, #{$prefix}#{$key}, '')} {
@if type-of($value) == 'map' {
@include modifiers($value, $attribute, $separator);
}
@else {
#{$attribute}: $value;
}
}
}
}
.text {
@include modifiers($colors, 'color', $separator: ':');
@include modifiers($font-sizes, 'font-size', '--');
}
.text-red {
color: #ff3538;
}
.text-grey {
color: #404145;
}
.text-grey:light {
color: #c7c7cd;
}
.text-yellow {
color: #ecaf2d;
}
.text-green {
color: #5ad864;
}
.text--small {
font-size: 12px;
}
.text--medium {
font-size: 14px;
}
.text--large {
font-size: 16px;
}
.text--x-large {
font-size: 18px;
}
.text--xx-large {
font-size: 20px;
}
@zachbryant
Copy link

Why isn't separator used in the modifiers mixin?

@raphaelobene
Copy link

@sarahdayan, this is awesome. Could you please explain how negative values (eg. -4px) can be supported? Is there a way to handle @media queries in the @mixin for handy breakpoint changes?

@Mozart-Alkhateeb
Copy link

@sarahdayan Amazing gist, I've built something nice with it.

@raphaelobene check how I'm using this to generate negative margin. For media I think you can use some condition as I'm doing here in the case of default. Also you can try wrapping the the class with media queries and passing different sizes but I'm not sure if it will generate the css you want but you can try it.

/** Custom CSS Variables **/
:root {
  --ion-space-xs: 4px;
  --ion-space-sm: calc(var(--ion-space-xs) * 2);
  --ion-space-md: calc(var(--ion-space-xs) * 3);
  --ion-space: calc(var(--ion-space-xs) * 4);

  --ion-negative-space-xs: calc(var(--ion-space-xs) * -1);
  --ion-negative-space-sm: calc(var(--ion-space-md) * -1);
  --ion-negative-space-md: calc(var(--ion-space-md) * -1);
  --ion-negative-space: calc(var(--ion-space) * -1);
}
$spaces: (
  xs: var(--ion-space-xs),
  sm: var(--ion-space-sm),
  md: var(--ion-space-md)
);

$negative-spaces: (
  xs: var(--ion-negative-space-xs),
  sm: var(--ion-negative-space-sm),
  md: var(--ion-negative-space-md),
  default: var(--ion-negative-space)
);

@mixin class-variations($args, $attribute: 'padding', $prefix: '') {
  @each $key, $value in $args {
    @if $key == 'default' {
      &#{$prefix} {
        #{$attribute}: $value;
      }
    } @else {
      &#{$prefix}-#{$key} {
        #{$attribute}: $value;
      }
    }
  }
}

// Generate padding variations
.ion-padding {
  @include class-variations($args: $spaces);
  @include class-variations($args: $spaces, $attribute: 'padding-top', $prefix: '-top');
  @include class-variations($args: $spaces, $attribute: 'padding-left', $prefix: '-start');
  @include class-variations($args: $spaces, $attribute: 'padding-right', $prefix: '-end');
  @include class-variations($args: $spaces, $attribute: 'padding-bottom', $prefix: '-bottom');
}

// Generate margin variations
.ion-margin {
  @include class-variations($args: $spaces);
  @include class-variations($args: $spaces, $attribute: 'margin-top', $prefix: '-top');
  @include class-variations($args: $spaces, $attribute: 'margin-left', $prefix: '-start');
  @include class-variations($args: $spaces, $attribute: 'margin-right', $prefix: '-end');
  @include class-variations($args: $spaces, $attribute: 'margin-bottom', $prefix: '-bottom');
}

.ion-negative-margin {
  @include class-variations($args: $negative-spaces, $attribute: 'margin-top', $prefix: '-top');
  @include class-variations($args: $negative-spaces, $attribute: 'margin-left', $prefix: '-start');
  @include class-variations($args: $negative-spaces, $attribute: 'margin-right', $prefix: '-end');
  @include class-variations($args: $negative-spaces, $attribute: 'margin-bottom', $prefix: '-bottom');
}

@amerrika
Copy link

Thanks for the article, very well explained!

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