thaumictom
thaumictom

Reputation: 453

Multiple classes with same styling with specific attributes to each class in SCSS

Assume the following code:

<div class="example">
  <div class="class-1">Class 1</div>
  <div class="class-2">Class 2</div>
  <div class="class-3">Class 3</div>
  <div class="class-4">Class 4</div>
  <div class="class-5">Class 5</div>
</div>
/* Code every class shares */
.example .class-1,
.example .class-2,
.example .class-3,
.example .class-4,
.example .class-5 {
    padding: 1em;
    font-family: sans-serif;
    /* More code... */
}

/* Code that is different */
.example .class-1 {
    color: red;
}

.example .class-2 {
    color: blue;
}

.example .class-3 {
    font-weight: bold;
}

.example .class-4 {
    background-color: darkcyan;
}

.example .class-5 {
    text-transform: uppercase;
}

Is there a way to avoid repeating yourself using SCSS? Please keep in mind that I am not looking for a way to iterate through a map with the attributes.

Upvotes: 1

Views: 4644

Answers (2)

disinfor
disinfor

Reputation: 11558

Here's a basic example of what you could do with the provided example code:

/* Code every class shares */
.example > div {
    padding: 1em;
    font-family: sans-serif;
    /* More code... */
    
    &.class {
        &-1 {
            color: red;
        }
        
        &-2 {
            color: blue;
        }
        
        &-3 {
            font-weight: bold;
        }
        
        &-4 {
            background-color: darkcyan;
        }
        
        &-5 {
            text-transform: uppercase;
        }
    }
}

That compiles to this:

/* Code every class shares */
.example > div {
  padding: 1em;
  font-family: sans-serif;
  /* More code... */
}
.example > div.class-1 {
  color: red;
}
.example > div.class-2 {
  color: blue;
}
.example > div.class-3 {
  font-weight: bold;
}
.example > div.class-4 {
  background-color: darkcyan;
}
.example > div.class-5 {
  text-transform: uppercase;
}

Because you are changing different properties for each .class-* element, you cannot avoid writing it out like this, unless you want to get into SASS Maps, which may work for you if you want to pre-define styles.

$elements : ( 
    1: ( 'color' : 'red', 'text-align' : 'left', 'font-size': '16px'), 
    2: ( 'color' : 'blue'), 
    3: ( 'font-weight' : 'bold')
    );


/* Code every class shares */
.example > div {
    padding: 1em;
    font-family: sans-serif;
    /* More code... */
    
    &.class {
        @each $index, $maps in $elements {
            &-#{$index} {
                @each $prop, $style in $maps {
                    #{$prop} : #{$style}
                }
            }
        }
    }
}

Compiles to:

/* Code every class shares */
.example > div {
  padding: 1em;
  font-family: sans-serif;
  /* More code... */
}
.example > div.class-1 {
  color: red;
  text-align: left;
  font-size: 16px;
}
.example > div.class-2 {
  color: blue;
}
.example > div.class-3 {
  font-weight: bold;
}

Upvotes: 0

Diego
Diego

Reputation: 495

Given your example, this is something I can think of in order to not repeat yourself too much using SCSS

.example {
    /* Code every class shares */
    [class^="class-"] {
       padding: 1em;
       font-family: sans-serif;
       /* More code... */
    }

    /* Code that is different */
    .class-1 {
        color: red;
    }

    .class-2 {
        color: blue;
    }

    .class-3 {
        font-weight: bold;
    }

    .class-4 {
        background-color: darkcyan;
    }

    .class-5 {
        text-transform: uppercase;
    }
}

Keep in mind that [class^="class-"] will affect all elements which contain classes that starts with "class-" like class-a, class-x, etc More details about attribute selectors: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

Upvotes: 2

Related Questions