Geoff
Geoff

Reputation: 6629

Optimizing sass code to reduce duplications

I have written the following padding modifiers which when compiled are supposed to remove padding.

SO i have

.no-padding{

  &--all{
   padding:0!important;
  }

 &--top{
  padding-top:0!important;
 }

 &--bottom{
  padding-bottom:0!important;
 }

 &--left{
  padding-left:0!important;
 }

 &--right{
  padding-right:0!important;
 }
}

This works in css eg: <div class="no-padding--all"> removes padding on all sides.But am checking on a way to optimize this further since i have similar repetition for margins as well.How further can i optimize this in sass.

Upvotes: 0

Views: 341

Answers (3)

Amaury Hanser
Amaury Hanser

Reputation: 3456

I would have another approach than the other answers.

I would use two maps and two @each functions.

First, I define the directions:

$directions: top, right, bottom, left;  

Then, the properties:

$properties: padding, margin;

The complete code:

$directions: top, right, bottom, left;
$properties: padding, margin;

/* This loop will create the .x-all classes */
@each $property in $properties {
  .no-#{$property}--all {
    #{$property} : 0 !important;
  }
}
/* This loop will create all the other direction specific classes */
@each $direction in $directions {
    @each $property in $properties {
    .no-#{$property}--#{$direction} {
      #{$property}-#{$direction} : 0 !important;  
    }
  }
}

Upvotes: 2

Sumanth Yedoti
Sumanth Yedoti

Reputation: 29

You can use a mixin

@mixin no-padding(
  $all: false,
  $left: false,
  $right: false,
  $top: false,
  $bottom: false,
 ) {
   @if($all) {
     padding: 0 !important;
   }
   @if($left) {
     padding-left: 0 !important;
   }
   @if($right) {
     padding-right: 0 !important;
   }
   @if($top) {
     padding-top: 0 !important;
   }
   @if($bottom) {
     padding-bottom: 0 !important;
   }

}

Usage:

.no-padding--all {
  @include no-padding($all: true);
}
.no-padding--left {
  @include no-padding($left: true);
}
.padding--left-only {
  @include no-padding($top: true, $right: true, $bottom: true);
}
.no-padding--vertical {
  @include no-padding($left: true, $right: true);
}

In addition, this gives you the power and flexibility to give arguments at your choice and you can write flexible classes, so you don't have to give multiple class names in HTML. (eg: padding--left-only, no-padding--vertical)

You can write a mixin to give property dynamically (I don't recommend it).

@mixin no-property(
  $property,
  $all: false,
  $left: false,
  $right: false,
  $top: false,
  $bottom: false,
 ) {
   @if($all) {
     #{$property}: 0 !important;
   }
   @if($left) {
     #{$property}-left: 0 !important;
   }
   @if($right) {
     #{$property}-right: 0 !important;
   }
   @if($top) {
     #{$property}-top: 0 !important;
   }
   @if($bottom) {
     #{$property}-bottom: 0 !important;
   }
}

usage:

.no-padding--left {
  @include no-property($property: 'padding', $left: true);
}
.no-margin--right {
  @include no-property($property: 'margin', $right: true);
}

Upvotes: 0

ElShahat
ElShahat

Reputation: 76

You can simplify this further:

.no-padding{
 padding: 0 !important;

 &--top{
  padding-top: 0 !important;
 }

 &--bottom{
  padding-bottom: 0 !important;
 }

 &--left{
  padding-left: 0 !important;
 }

 &--right{
  padding-right: 0 !important;
 }
}

By this you can use .no-padding directly instead of .no-padding--all.

You can also simplify the naming of your modifiers like using one letter instead of --top, --right, --bottom, --left to --t, --r, --b, --l otherwise everything else is OK.

A Mixin can also do the job:

@mixin no-padding($dir){
    @if $dir == 'top' {
        padding-top: 0 !important;
    }

    @if $dir == 'right' {
        padding-right: 0 !important;
    }

    @if $dir == 'bottom' {
        padding-bottom: 0 !important;
    }

    @if $dir == 'left' {
        padding-left: 0 !important;
    }

    @if $dir == 'all' {
        padding: 0 !important;
    }
}

And include it to your classes like that:

.no-padding{
 @include no-padding(all);

 &--top{
  @include no-padding(top);
 }

 &--bottom{
  @include no-padding(bottom);
 }

 &--left{
  @include no-padding(left);
 }

 &--right{
  @include no-padding(right);
 }
}

Note that you can use this mixin @include no-padding($dir) with any class.

Upvotes: 0

Related Questions