2

I know this is a very asked question, but I can't seem to find the proper way of setting my project. In Angular 12, I'm trying to set a file of variables to share among all components without importing it in every scss file, and I'm trying to set it up in the styles.scss file, but it doesn't seem to be working properly. I'm getting an "undefined variable" error.

My variables file:

$primary-color: #efefef;
$light-color: #454758;
$main-font:  #ACADB4;
$main-font-regular: #6E707D;
$main-font-light: #3c3c3c;
$rich-black: #001011;
$primary-white: #fafafa;

Here's how I'm importing it in styles.scss:

/* FONT AWESOME */
@import "~@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "~@fortawesome/fontawesome-free/scss/solid.scss";
@import "~@fortawesome/fontawesome-free/scss/regular.scss";
@import "~@fortawesome/fontawesome-free/scss/brands.scss";

/* MDB CSS */
@import "~mdb-angular-ui-kit/assets/scss/mdb.scss";

/* VARIABLES */
@import "styles/_variables.scss";

My angular.json file:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1, 
  "newProjectRoot": "projects",
  "projects": {
    "CVWebPage": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/CVWebPage",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css", 
              "src/styles.scss",
              "src/styles/_variables.scss"
            ],
            "stylePreprocessorOptions": {
              "includePaths": [
                "./src/styles" 
              ]
            },
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/popper.js/dist/umd/popper.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js"
            ],
            "vendorChunk": true,
            "extractLicenses": false,
            "buildOptimizer": false,
            "sourceMap": true,
            "optimization": false,
            "namedChunks": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          },
          "defaultConfiguration": ""
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "CVWebPage:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "CVWebPage:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "CVWebPage:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.scss",
              "src/styles/_variables.scss"
            ],
            "scripts": [
              "./node_modules/jquery/dist/jquery.slim.min.js",
              "./node_modules/popper.js/dist/umd/popper.min.js",
              "./node_modules/bootstrap/dist/js/bootstrap.min.js"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "CVWebPage:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "CVWebPage:serve:production"
            }
          }
        }
      }
    }},
  "defaultProject": "CVWebPage"
}

And I'm just using it in a Component scss file like this:

color: $primary-white;

My project structure:

enter image description here

I've tried doing the same this post does but couldn't make it work: How to use global scss files in angular-cli project

Thanks for the help!

magalenyo
  • 275
  • 6
  • 17
  • If i understand correctly you'd like to have your sass variables available inside all your files, without importing the variable files directly. In my opinion it doesn't work cause the styles param in the angular.json config is rather included at build time, than what you expect to be available for pre-processors. Most of the projets i worked on had an import at the begining of every scss file importing variables and functions. – Simplicity's_Strength Dec 25 '21 at 18:26
  • In this example, https://pantaley.com/blog/Organize-CSS-Preprocessors-like-Sass-or-Less-in-Angular-Cli although `stylePreprocessorOptions` is added, he's still using imports. It only has the upside of shortening urls – Simplicity's_Strength Dec 25 '21 at 18:31
  • hi @Simplicity's_Strength I think that's exactly what I'm trying to do. The posts explains that he imports the colors file in the styles.scss so he can use them wherever he wants. But that's what I'm trying to do, but still failing at it :( – magalenyo Dec 25 '21 at 19:35
  • Potential duplicate of https://stackoverflow.com/questions/55131372/global-scss-variables-for-angular-components-without-importing-them-everytime – Simplicity's_Strength Dec 25 '21 at 20:00
  • 1
    @Simplicity's_Strength I'd still like to make it work this way, though. – magalenyo Dec 25 '21 at 20:16
  • just try to import like this @import "./styles/_variables.scss"; – nativelectronic Dec 25 '21 at 22:09
  • @magalenyo As stated in this feature request reply on the angular-cli github https://github.com/angular/angular-cli/issues/7548#issuecomment-326988341 It's not something possible with the default angular-cli, maybe extra webpack config and messing with the sass-resources-loader plugin. Have no idea how to do it though, suggest making a sass variables and mixins index.scss and importing in all files at this point. – Simplicity's_Strength Dec 27 '21 at 09:55

1 Answers1

2

In order to use varibles in css, you have to do something like this:

  1. In your '_variables.scss', define your variables inside :root*, something like:
:root {
    // Your colors    
   --color-primary-color: #efefef;
   --color-light: #454758;
   --color-main-font:  #ACADB4;
   --color-primary-white: #FFFFFF;
... 
}
  1. In 'styles.scss', you have already well imported your variables file:
/* VARIABLES */
@import "styles/_variables.scss";

  1. Then, in your styles.scss (or in another scss file of your choice), use these variables with var(), like this:
color: var(--color-primary-white);

I leave you HERE a link to an article about CSS Custom Properties (vars) with SASS/SCSS (a practical architecture strategy)

  • Hi, thanks for the reply! Yes, I have seen this way of doing it in other posts, but didn't like it that much since I was used to using imports and found several posts that made it work. Any difference between this and the way I was proposing? – magalenyo Dec 25 '21 at 20:15
  • 1
    `--myvar` is example of css native vars, that are working on runtime and can be overwritten on runtime. for now it is a prefered variables, unless you are supporting old browsers like IE11. before this feature was working in all browsers, scss $variables existed to kinda partially polyfill them, and now they are not required – Andrei Dec 25 '21 at 23:38