Variable scope in SASS mixins [duplicate] - sass

This question already has answers here:
How to assign to a global variable in Sass?
(2 answers)
Closed 7 years ago.
I'm trying to wrap my brain around this one and hopefully someone here can enlighten me. I have this code as an example:
#mixin stuffs() {
color: $color;
}
$color: #000;
.single {
$color: white;
#include stuffs();
}
I would expect that $color inside the scope of .single would override the global $color value, however it does not. Can someone explain why? What am I missing here?

Ok - let's see if I can break this down using the example you gave.
#mixin stuffs() {
color: $color;
}
$color: #000;
.single {
$color: white;
#include stuffs();
}
You're expecting that the local variable version of $color (i.e. white) would be displayed in the .single selector rather than black.
But you need to separate the local scope of .single from the local scope of the mixin stuffs. They are not the same thing. You would still need to "use" the local variable version of $color (i.e. white) within the .single selector like this:
#mixin stuffs() {
color:$color;
}
$color:#000;
main
{
$color:white;
#include stuffs();
color:$color;
}
Please let me know if I've missed something for you and check out http://webdesign.tutsplus.com/articles/understanding-variable-scope-in-sass--cms-23498 for more information about scope.

Related

#mixin format is it ok to not have ()?

Learning about #mixin and I came across this code. How come the hover-not-disabled on the first line is not followed by () and is it ok to do this? Thanks in advance!
#mixin hover-not-disabled {
&:not([disabled]):hover {
#content;
}
}
.button {
border: 1px solid black;
#include hover-not-disabled {
border-color: blue;
}
}
Its fine. It won't cause any errors, since (…) is meant to contain the arguments which when using a #mixin are usually needed, however in this case the editor wants to pass the mixin into mutliple elements and then edit the #content.
From a subjective point of view, I'd recommned to always include the () for the sake of consistency even if they would be empty, so when quickly scanning the code, nothings seems odd.
So this would be my approach, but generally spoken, it's totally fine to leave them in such cases.
#mixin hover-not-disabled() {…}
#include hover-not-disabled();

Ampersand and mixins in SCSS

Searched but can't find an answer..
I have an element which gets generated (by an external platform) with the following classes: p-button and button.
Now the SCSS is like this:
.p-button {
&.button {
margin: 10px;
}
}
But I want to refactor using mixin includes (this is a big project so there is no other way of making this code better except using mixins). The mixin takes the given selector and applies a . to it. I can't change the mixin, as it is used by many other teams, so I can't pass the ampersand together with the selector. I tried this:
.p-button {
& {
#include button-appearance("button") {
margin: 10px;
}
}
}
But that doesn't work (puts a space between it). You can't do this:
.p-button {
&#include button-appearance("button") {
margin: 10px;
}
}
Anyone have a clue?
EDIT: Here is the mixin
#mixin button-appearance(
$appearance-class,
$show,
$background-color,
$background-image,
$background-position) {
$sel: $button-selector;
#if $appearance-class {
$sel: $sel + '.' + $appearance-class;
}
#{$sel} {
#include normalized-background-image($background-image);
#include show($show);
background-color: $background-color;
background-position: $background-position;
}
#content;
}
EDIT 2: Here is the $button-selector (I can not edit this in the platform, but maybe overwrite it in my own project?)
$button-class: 'p-button';
$button-selector: '.#{$button-class}';
Everyone, finally found the solution. I just removed the &.button from the .p-button mixin include and now it works:
#include button-appearance ("button") { *styles* }
#include button-appearance () { *styles* }
Edited the answer after the original question was edited adding the used and un modifiable mixin
The original mixin does not append the ‘#content’ passed to the mixin to the generated selector. So if you cannot modify the original mixin, the only way is to add your properties outside the mixin. According to the mixin the selector will match a predefined ‘$button-selector’ variable, so it won’t use your class.
So, if you want to use the same class defined in ‘$button-class’, try the following:
#{$button-selector}.button {
margin: 10px;
}
Will output:
.p-button.button {
margin: 10px;
}

Mixin background gradient with background image.png

I have a mixin declared more or less like this
#mixin color-background {
background: yellow;
}
And i would wish to use this color as background of a png. but i cant seem to be able to mix the two
now what i would like to do is for example
.myImageWithBackgroundColor{
background: url(image.png),#include color-background
}
How can i acheive this with SASS and mixin?
You could store the background value of the mixin to a variable, and then use the variable instead of the whole mixin in the second code snippet.
$my-color: yellow;
#mixin color-background {
background: $my-color;
}
.myImageWithBackgroundColor{
background: url(image.png) $my-color;
}

Giving default arguments to mixins when there is more than one variable

I am trying to make a #mixin where I want to give a default value to the first variable but not to the second variable.
#mixin myCoolFont($color:purple, $size) {
color: $color;
font-size: $size;
}
Now when I call that mixin I do something like this:
p {
#include myCoolFont(white, 63px)
}
When compiling it outputs an error that says $size must come before any other arguments.
Please, tell me, what am I doing wrong?
You just do as error says, it will work, simple change order of arguments so that last argument(s) are those with default values. In your case:
#mixin myCoolFont($size, $color:purple) {
color: $color;
font-size: $size;
}
p {
#include myCoolFont(63px, white)
}

Access property of current class, such as background-color, in SASS [duplicate]

This question already has answers here:
Sass - Manipulate inherited property?
(4 answers)
Closed 7 years ago.
I keep finding myself wanting to refer to a property of the current class when working in SASS. Usually this comes up as a way to make things more reusable or handle interactions. For example:
.circle
background-color: $brandColor
.circle:hover
background-color: $brandColor + 50
.square
background-color: $brandColor1
.square:hover
background-color: $brandColor1 + 50
I would prefer to write the code more DRYly, like this:
.circle
background-color: $brandColor
.square
background-color: $brandColor1
.circle:hover,
.square:hover
background-color: &background-color + 50
Is this, or something similar, possible in SASS?
No, there is nothing like that in Sass. You would need to use a mixin to get the DRYness you're looking for.
#mixin colorize($color) {
background-color: $color;
&:hover {
background-color: $color + 50;
}
}
.circle {
#include colorize($brandColor1);
}
.square {
#include colorize($brandColor2);
}

Resources