Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

CSS Sass Basics (retired) Advanced Sass Concepts Advanced Mixin Arguments

Zoe Lingard
Zoe Lingard
2,467 Points

Default Styles

Hi there,

I was wondering if someone might be able to help. I've been watching the above course and I'm trying to create a style guide to use on projects. Using Sass I'm trying to create a mixin that creates some classes and corresponding button background colors. If it worked I would be able to use it repeatedly which would be satisfying!

The resulting CSS I'm looking for is

.alert--success { background-color: green; color: white; text-align: center; padding: 0.5em; margin: 0.5em 0; font-weight: bold; } .alert--info { background-color: blue; color: white; text-align: center; padding: 0.5em; margin: 0.5em 0; font-weight: bold; } .alert--warning { background-color: red; color: white; text-align: center; padding: 0.5em; margin: 0.5em 0; font-weight: bold; } .alert--danger { background-color: purple; color: white; text-align: center; padding: 0.5em; margin: 0.5em 0; font-weight: bold; }

So nothing changes but the background color and that color corresponds to the class name in a declared variable e.g. for .alert--danger the variable used for background-color is $danger.

This works but I'm frustrated by it's repetition:

%alert { background-color: $alert; color: $white; text-align: center; padding: 0.5em; margin: 0.5em 0; font-weight: $bold-type; }

.alert { @extend %alert; &--success { background-color: $alert--success; } &--info { background-color: $alert--info; } &--warning { background-color: $alert--warning; } &--danger { background-color: $alert--danger; } }

I would like to get it to something along the lines of:

.alert { @extend %alert; @include alert-color(success info warning danger) }

where the mixin is

@mixin alert-color($variable) { @each $variable in success, info, warning, danger { &--#{$variable} { background-color: $alert--#{$variable}; } } }

This doesn't work because when the mixin calls $alert--#{$variable}; is it looking for a variable called $alert - which doesn't exist. I want it to actually be looking for a variable named $alert--success for example. I have tried brackets and double $ but nothing is working!!

Is this a good use of Sass? Is it possible to achieve? Am I cracking an egg with a sledgehammer?

Thanks

1 Answer

Stephan L
Stephan L
17,821 Points

I know this an old question, but it's a good puzzle. Maybe you're still trying to solve it?

Maybe you could have an 'alert' class that has the common formatting rules, and then specific classes for each button that assigns the background color? So, each div would be "<div class="alert success>" and so on? Following that format, here's what I did:

@mixin alert(){
    @each $i in success, info, warning, danger {
        @if $i==success {
            .alert--#{$i} {
                background-color: green;
            }
        } @else if $i==info {
            .alert--#{$i} {
                background-color: blue;
            }
        } @else if $i==warning {
            .alert--#{$i} {
                background-color: red;
            }
        } @else {
            .alert--#{$i} {
                background-color: purple;
            }
        }
    }
        .alert {
            color: white;
            text-align: center;
            padding: 0.5em;
            margin: 0.5em;
            font-weight: bold;
            }
}

@include alert();

That should compile to:

alert--success {
  background-color: green; }

.alert--info {
  background-color: blue; }

.alert--warning {
  background-color: red; }

.alert--danger {
  background-color: purple; }

.alert {
  color: white;
  text-align: center;
  padding: 0.5em;
  margin: 0.5em;
  font-weight: bold; }

I'm sure there's a even more DRY way to code this, but that seems to work.