I have a mixin that draws a button like this:
@mixin button {
border: 1px solid $orange;
background: $orange;
padding:0;
height:27px;
text-transform: uppercase;
color:white;
display:block;
// if I'm styling an a tag padding-top:10px 10px 0 10px;
}
I want to be able to do this:
button.my_button {
@include button;
}
a.my_button {
@include button;
}
The second one requires some additional custom code to work nicely. Is is possible to include a conditional in the mixin that checks to see if I'm styling an a tag, or do I need write a second mixin?
Within a mixin, no. If you're open to extends, you can get pretty close:
$orange: lighten(orange, 10%);
%button {
border: 1px solid $orange;
background: $orange;
padding:0;
height:27px;
text-transform: uppercase;
color:white;
display:block;
}
a%button {
padding-top:10px 10px 0 10px;
}
button.my_button {
@extend %button;
}
a.my_button {
@extend %button;
}
Compiles to:
button.my_button, a.my_button {
border: 1px solid #ffb733;
background: #ffb733;
padding: 0;
height: 27px;
text-transform: uppercase;
color: white;
display: block;
}
a.my_button {
padding-top: 10px 10px 0 10px;
}
Starting with 3.4 we have the ability to examine and manipulate the selector.
$orange: lighten(orange, 10%);
@mixin button {
border: 1px solid $orange;
background: $orange;
padding:0;
height:27px;
text-transform: uppercase;
color:white;
display:block;
@if is-superselector('a', &) {
padding-top: 10px 10px 0 10px;
}
}
button {
@include button;
}
b a.foo {
@include button;
}
Output:
button {
border: 1px solid #ffb733;
background: #ffb733;
padding: 0;
height: 27px;
text-transform: uppercase;
color: white;
display: block;
}
b a.foo {
border: 1px solid #ffb733;
background: #ffb733;
padding: 0;
height: 27px;
text-transform: uppercase;
color: white;
display: block;
padding-top: 10px 10px 0 10px;
}
As of this writing, there's no way to inspect the context / element type in a conditional. But you can set a default in your conditional, and thus simplify the default case of the mix-in.
Here's an example:
@mixin button($type: normal) {
border: 1px solid orange; background: orange; color: white; display: block;
@if $type == anchor { padding: 10px 10px 0 10px; }
@else { padding: 0; }
}
button.my_button {
@include button;
}
a.my_button {
@include button($type: anchor);
}
See it in action at http://sassmeister.com/gist/6284603.
It looks like this functionality is (maybe) planned for Sass 3.3 with the @at-root
directive: https://github.com/nex3/sass/issues/774.
Why don't you use @content directive.
$orange: #000;
@mixin button {
border: 1px solid $orange;
background: $orange;
padding: 0;
height: 27px;
text-transform: uppercase;
color: white;
display: block;
@content;
}
button.my_button {
@include button;
}
a.my_button {
@include button {
padding-top:10px 10px 0 10px;
};
}
Using this approach you will keep your mixin untouched and you will still have the functionality that you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With