Is it possible to create a local/private sass mixin? - css

I have three sass files: a.scss, b.scss, c.scss
a.scss:
#mixin font($size, $color){
font-size: #{$size};
color: #{$color}
}
p{
#include font(10px, blue)
}
b.scss:
#mixin font()
{
..
}
c.scss
#import a.scss
#import b.scss
I think the mixin font() in b.scss override the mixin font($size, $color) in a.scss.
p{
#include font(10px, blue) // use mixin font() in b.scss, error
}
Is it possible to create a local/private sass mixin? Or all mixins in sass are global, I have to give them unique name for each mixin?

Mixins within selectors are local to that selector just like Sass variables are. These two mixins are independent of each other:
.foo{
#mixin my_color(){
color: #ffcc00;
}
#include my_color;
}
.bar{
#mixin my_color(){
color: #00ffcc;
}
#include my_color;
}
So, to answer your final question - only mixins defined at the global level are global, and you can otherwise reuse names safely. In your example, if your a.scss, b.scss and c.scss are structured to define different overarching classes (eg .header, .main, .footer) you can have local font mixins for each.
Related: Localizing/Scoping a sass mixin.

UPDATE: Now with the new #use rule you can add private members just by starting its name with either - or _
More info here:
https://sass-lang.com/documentation/at-rules/use#private-members

You are right. Just as in a typical CSS file, your sass project is compiled top down. So a mixin sharing the same name as a previous one will overwrite it. If you wish to use the original mixin in c.scss you would have to redefine it.

Related

(S)CSS define global color

So I would like to define a global color in my Angular project in the styles.scss stylesheet.
I know I can defined global variables like this
:root {
--blueish: #658bc7;
}
and then in other styles(heets) reference to it
p {
color: var(--blueish);
}
But this is NOT a globally defined color. This is a globally defined variable.
We could for example do
p {
color: aliceblue;
}
and this does work since aliceblue is globally defined along with a lot more preset colors. Is there a way for me to ADD a color to this list using (S)CSS? If not, would it be possible in less or SASS?
You can assign in SCSS vars with $varName. Important note if you like to use dash or underScore in your varnames. For the SASS compiler, $var-name is the same as $var_name. You have to take that into consideration.
SCSS
$blueish: #658bc7;
p {
color: $blueish;
}
Will compile to CSS:
p {
color: #658bc7;
}
You Can Define and Assign Variables in scss/sass Like This
$blueish: #658bc7;
p {
color: $blueish;
}
Notice that in sass/scss files named "blablabla" are globally scope
while files named "_blablabla" are not globally scoped and must be imported by.
You Must Have one globally file in sass/scss for example named "style.scss" that imports all scss/sass files in it for example:
/*
This File is only for imports
*/
#import "./libraries/_variables.scss";
#import "./libraries/_mixins.scss";
#import "./layouts/_header.scss";
#import "./pages/_about.scss";
Also, you can not add "_" and ".scss" in the importing it is not necessary for your editor will understand it for Example :
#import "./libraries/variables";
#import "./libraries/mixins.scss";
#import "./layouts/_header";
They are the same as the above example!

Css variables declared in :root block in styles.scss are invalid

In my angular 11 app I am trying to globally use css variables to declare global colors.
In my styles.scss I have:
:root{
--primary : #0b68e8;
--secondary:#ABCFFF;
}
.test-class{
background: var(--primary);
}
When I am applying that class in one of mine components I can see that var was not properly taken from declared variables:
I tried to find any solution , but cant resolve it. Do you maybe know what is wrong here?
try
.test-class{
background: #{var(--primary)};
}
BTW, if you're using sccs, why not use sass variables?
$primary: #0b68e8;
.test-class{
background: $primary;
}

Unable to set SCSS variable to CSS variable?

Consider the following SCSS:
$color-black: #000000;
body {
--color: $color-black;
}
When it is compiled with node-sass version 4.7.2, it produces following CSS:
body {
--color: #000000;
}
When I compile the same SCSS with version 4.8.3 or higher, it produces following:
body {
--color: $color-black;
}
What am I missing? I checked release logs, but could not found anything useful. Also, I wonder if this change is genuine why does it have only minor version change? Should it not be a major release?
Also, what is my alternative? Should I use Interpolation?
Just use string interpolation:
$color-black: #000000;
body {
--color: #{$color-black};
}
Apparently the old behaviour is not intended and violated the language specs of SASS:
CSS variables mixed with SCSS variables don't emit proper CSS in 4.8+
CSS variables aren't properly compiled
Assigning SASS variables to CSS Variables (Custom Properties) no longer works
scss and css
I found a workaround to mapping the scss variables to css variables.
See Terry's answer for better use
Scss:
// sass variable map
$colors: (
color-black: #FFBB00
);
// loop over each name, color
:root {
// each item in color map
#each $name, $color in $colors {
--#{$name}: #{$color};
}
}
Css:
:root {
--color-black: #FFBB00;
}
I had an issue with older sass versions.
Trying to compile a list of variables coming from an array, it would get stuck with the double dash. Here's my solution in case it helps someone
$var-element:'--';
:root {
#each $color in $color-variables {
#{$var-element}#{nth($color, 1)}: #{nth($color, 2)};
}
}

Overriding Sass mixin in view template dynamically

I've defined a Sass mixin and used it in a class styling. I'm using the class in template. I need to decide the color on runtime. So I'm trying to override mixin. But its showing in #ff0000 the color I defined in mixin initially.
For some reason I can't use an extra class, What could be the best solution in this scenerio.
My stylesheet app.scss
#mixin mx-color {
color: #ff0000;
}
.my-color {
#include mx-color;
}
Angular template view app.html.haml
:css
#mixin mx-color {
color: {{custom_color}}; // custom_color contains hex-color to replace
}
%body
%p.my-color
This text must show-up in custom color but its showing the default color.
Please check the compiled HTML/CSS output. I don’t think it is possible to just overwrite a mixin and expect the SASS blocks where the mixin was used to update automatically.

Sister color scheme in SASS [duplicate]

Is there any way I can set my color variables depending on what class is on the html element? Or any other way to achieve this same goal?
html {
&.sunrise {
$accent: #37CCBD;
$base: #3E4653;
$flat: #eceef1;
}
&.moonlight {
$accent: #18c;
$base: #2a2a2a;
$flat: #f0f0f0;
}
}
This is basic theming. You would either want to use a mixin or include to do multiple themes in a single CSS file. This is how you would go about it using includes:
_theme.scss
section.accent {
background: $accent;
}
.foo {
border: $base;
}
.bar {
color: $flat;
}
main.scss
html {
&.sunrise {
$accent: #37CCBD;
$base: #3E4653;
$flat: #eceef1;
#import "theme";
}
&.moonlight {
$accent: #18c;
$base: #2a2a2a;
$flat: #f0f0f0;
#import "theme";
}
}
You could just as easily make a mixin that takes 3 colors as its arguments to use in place of the include:
#mixin theme($accent, $base, $flat) {
// .. do stuff ..
}
Unfortunately, Sass/Scss files need to get compiled into Css files, in order to be supported in your web-browser.
Since Css files don't support variables, you can only set a variables value in the Scss template, because the Sass compiler will replace the var. (in every position, the var. has been used), with the given value.
That means, that it does not help to change the color of the variable, depending on what class is included in the Html file, because the Css file won't contain any variables.
The only way you could do such thing, is by:
reading the Html file to find out what class has been used,
than changing the Scss template variables to the right color value
and compiling the Scss template into an Css file
If you like to use JavaScript, you can do this:
You will need an HTML element with an Id and a Class (the one that will decides, what color to use).
<exampleTagg id="Target" class="Sunrise">...</exampleTagg>
Next, you will need to add some JavaSript
var CurrentColor = document.getElementById("Target").className;
if (CurrentColor == "sunrise") {
document.exampleTagg.style.exampleProperty = "#37CCBD";
}
else if (CurrentColor == "moonlight") {
document.exampleTagg.style.exampleProperty = "#18c";
}
(the first line will declare a variable, that contains the value of our exampleTagg element (the one with the "Target" id), then the if statement will find out the name of our class (sunrise or moonlight) and last, we will change the background of our exampleTagg to the color we like to)
To use this example for your own purposes, replace the exampleTagg with some real tagg and change the exampleProperty to an valid Css property.
Notice, that you will not need Scss for this job (u can still use it), because JavaScript will access your compiled Css file.

Resources