I am using Angular5 with sass v1.3.2.
I want to be able to change a color that is used extensively in the scss files of my single page app in runtime (not by compiling new files).
The color is defined globally in my _variables.css as:
$brand: #123123;
And for example used as:
h1 {
color: $brand;
}
I learned that I can modify the color if I am using CSS variables such as:
# CSS
:root {
--brand: #123123
}
#JS
document.documentElement.style.setProperty('--brand', '#456456');
# OR
document.querySelector(':root').style.setProperty('--brand', '#456456');
However to be able to do that using SCSS, I needed to use css-vars mixin as such:
$brand: #123123;
:root {
#include css-vars((
--brand: #{$brand},
));
}
And use it as:
h1 {
color: var(--brand);
}
Two problems:
Actually, still --brand is not showing at root.
Also, the CSS generated in <script type="text/css"> by angular-cli does not have --brand anywhere, it is actually compiling the CSS variable into #123123 so the output is:
h1 {
color: #123123;
}
Any ideas about how can I achieve changing a global color in runtime? Or how to get my CSS in :root and then how to get SASS to not compile it?
UPDATE
As #JonUleis has showed, there is no need for using css-var. Now the var --brand shows in the DOM at :root.
However, now color: var(--brand); line still does not show in the CSS, and h1 doesn't have a color style at all.
After updating node-sass to the latest 4.9.0 from 4.8.3, it worked great.
You're likely on an outdated version of node-sass that wasn't yet compatible with the syntax for CSS custom properties.
Here's your example code compiling successfully using Sassmeister without using the css-vars mixin:
Related
I just added sass to my create-react-app project. When I hardcode colour values, the styling is updated accordingly. But when I try to make use of some scss methods, the new styles are ignored.
e.g. This works fine...
:root {
--title-blue: #2086c3;
}
...This does not...
$color-test: black !default;
:root {
--title-blue: mix($color-test, white, 50%);
}
...neither does this
:root {
--title-blue: $color-test
}
I can import the newly-renamed .scss files and all the styling remains consistent, so I don't think this is a compilation error.
Any ideas why this might be? I'm using node-sass v4.14.1 because node sass 5 was giving me a react error.
I think you can try
$color-test: #000000;
:root {
--title-blue: #{$color-test};
}
A couple of years ago Sass stopped supporting the assignment of Sass variables to CSS variables. It seems that it was never intended to support it and, it was a bug that violated the SASS language spec. Using string interpolation solves this problem.
You can read more about it in this Github issue of the Sass language:
https://github.com/sass/node-sass/issues/2336
In my scss file I am importing a third-party css file
#import 'icons/third-party-icons/style';
Unfortunately, this style is missing the value for the color style
.mySelector {
content: "\eac2";
margin-left: -1em;
color: ;
}
As expected, node-sass is throwing the following error:
ModuleBuildError: Module build failed (from
./node_modules/sass-loader/lib/loader.js):
color: ;
^
Style declaration must contain a value
Is there any way to configure node-sass to ignore this invalid property?
In my opinion, that error report is there for a reason, you shouldn't have empty definitions as that is technically an error. In unminified CSS you wouldn't have an issue it would just appear as strikethrough in the element inspector in the browser, but in this case you break the minify process.
Instead of importing it you can download the CSS code if possible and save it in your project locally then solve the issues manually. It won't matter what you do later in your CSS file, the error will appear. Or else you can try to link the CSS in the header. If you are using PHP or similar serverside scripting then create a separate header.php (for example) and include it into every file. This way you will need to copy and paste the link once and you can access the style at every page.
You could override the imported css. The code is looking to use a value, but can't because it's null.
You could include in your style tags:
.mySelector {
color: black !important;
}
That !important will override whatever is imported from the stylesheet, and you class in the body will use that color instead of trying to use the null color.
In my Nuxt app I load all my SASS thus:
css: [
'~assets/scss/main.scss'
],
It works perfectly, except when I'm trying to use some SASS variable from within a component.
<style lang="scss">
.container {
background-color: $white;
}
</style>
In this case I get this error message:
SassError: Undefinied variable: $white
Yet, all of the SCSS contained in the SASS file where the variable is defined works throughout the app.
It is as if the app as a whole knew these files, but each individual component doesn't.
What's going on?
Most of the other answers don't take into account that Nuxt.js hides all the Webpack setup and forces you to do everything through nuxt.config.js.
My guess is that Webpack isn't compiling all the SCSS declarations together and therefore can't find the variable.
It's been a few months since I had this issue so things may have changed but here goes...
Make sure you have the correct Node packages installed (Nuxt DID NOT do this by default for me) npm i -D node-sass sass-loader
Add your CSS & SCSS files to the css: [] section of nuxt.config.js Order matters here so make sure things like variables are added before things that use them if you have separate files.
If you're using layouts (I think that's the default Nuxt setup) make sure that layouts/default.vue has a <style lang="sass"></style> block in it. If I remember correctly this can be empty but had to exist. I only have one layout but it may need to exist in all of them.
If all that seems like too much of a pain, there's a Nuxt Plugin that takes most of the work/management out of that process. Nuxt Style Resources Module
The confusing part is that:
styles from scss files CAN be loaded like this
//nuxt.config.js
css: [
'~assets/scss/main.scss'
],
//global scss file
$varcolor: black
h1{background: $varcolor}
BUT
the variables inside CAN NOT be used inside a component
//inside component
.component {background: $varcolor} // DOES NOT WORK
I also suggest the use of the nuxt style resource module:
https://github.com/nuxt-community/style-resources-module
new founded solution, checked and it's work. Founded here
add #nuxtjs/style-resources
export default {
css: [
'vendor.min.css'
],
modules: [
'#nuxtjs/style-resources'
],
//You will have to add this new object if it doesn't exist already
styleResources: {
scss: ['./assets/scss/main.scss'] // here I use only main scss with globally styles (variables, base etc)
},
}
it's strange, but if u change tilda (~) to dot(.), it's help for someone
from css: [ '~assets/scss/main.scss' ] to css: [ './assets/scss/main.scss' ]
this solution finded here
Us should either load the scss in your component
<style lang="sass">
#import 'path/to/your/_variable.scss'; // Using this should get you the variables
.my-color {
color: $primary-color;
}
Or adding the following to you to your vue.config.js
module.exports = {
css: {
loaderOptions: {
sass: {
data: `#import "#/pathto/variables.scss";`
}
}
}
};
Ref:
SassError: Undefinied variable: $white
Each <style lang="scss"> is compiled individually. You need to #import the file which defines $white into your component before the parser knows what $white means.
This is why most frameworks keep their variables in a _variables.scss file which is imported in all the other SCSS files/contexts.
The _variables.scss is not even loaded in the page, because in most cases it doesn't actually contain any rules. It only contains variable definitions which are imported into other .scss files, which output .css.
Ref:
Yet, all of the SCSS contained in the SASS file where the variable is defined works throughout the app.
If you import an SCSS file in your vue.config.js the output will be an ordinary <style> tag. Its contents will be generated at compile/build time and will result into some CSS (which apply to the entire document).
Unless specifically imported into the component SCSS, (using an #import command), the compiler will not know what $white means.
There is an important distinction to make between compilation context and browser context. Compilation happens at compile time (most likely in node-sass). Browser context is the actual browser, which only understands the CSS resulted from compilation.
How does Vue only apply style rules to the parent and not to the children with the same class? That's achieved by scoping.
It means applying a custom data-v-{key} attribute to all selectors in the generated <style> tag and to all elements the style should apply to.
See this example and inspect it using your web console: https://codesandbox.io/s/vue-template-ge2hb
It produces this markup:
As you can see, the scoped CSS has an extra [data-v-763db97b] added to the selector, which means it only applies to elements having that data attribute.
I'd like to define my own color variables in my SCSS, but how?
I checked this website and did everything that is described there.. but it doesn't work.
I have installed a preprocessor already!
Furthermore I tried to create a color-map and access the color with map-get.. doesn't work either.
colors.scss file
$yellow_100: #FFC819;
style.scss file with a colors.scss import
h1 {
color: $yellow_100;
}
I also tried this:
colors.scss file
$colors: (
color: #FFBB00
);
style.scss file
h1 {
color: map-get($colors, color);
}
Neither of them works.
SASS compiler preserves $ in output CSS and doesn't recognize $yellow_100 as a SASS variable. Use Interpolation to access variable's value instead of its nameājust put it between #{ and }.
So your code should look like:
$yellow_100: #FFC819;
h1 {
color: #{$yellow_100};
}
Interpolation isn't used in old code examples. That's because SASS developers changed the syntax approximately in July, 2017, making interpolation mandatory for SASS variables. Here is more details on this.
Install sass with npm -g install sass
Create these two source files:
// _colors.scss
$yellow_100: #FFC819;
// style.scss
#import './colors';
h1 {
color: $yellow_100;
}
Execute sass ./style.scss ./output.css to compile your code
Add <link rel="stylesheet" type="text/css" href"[path to output.css]" /> to your HTML
Make sure you're using single colons to prefix your root header tag in your .scss files.
i.e :root{} and not ::root{}
I want to define CSS variables like in Sass.
Something like:
.someClass {
background-image: $imageLink;
color: $someColor;
}
And i Want to define $imageLink and $someColor in my class or in json file.
Can i do this without Sass or Less? (Or without css variables, because it does not supported in IE.)
I an using angular2 and webpack in my project.
Of course you cannot set SASS variables at run-time, because by that time the SASS has already been compiled.
A classic approach is to instead think in terms of "themes", and select a theme by a class on a higher-level element (such as body). So you could have
.darktheme .someClass { color: white; }
.lighttheme .someClass { color: black; }
Now from your JS you can change the theme with
document.body.classList.add('darktheme');