angular-cli: Can't access Sass Global Variables in components scss

I have a habit of importing my _variables.scss and _mixins.scss into my root src/style.scss file

@import 'styles/base/_variables.scss';
@import 'styles/base/_mixins.scss';
@import 'styles/helpers/flexbox.scss';
* {
    padding: 0;
    margin: 0;
}

body{
	padding: 4%;
	font-family: sans-serif;
}

But when I’m trying to access the variables in my components.scss, it’s giving me an error color: $primary-color;

Isn’t there a way I can achieve this simply? Please Help.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 21
  • Comments: 29 (6 by maintainers)

Most upvoted comments

Seriously there is no better way for this?

You need to include styles/base/_variables.scss in each and every file where you need to use variables. Same goes for mixins. The actual content of those files will not be included in the final build and wont impact the build size in any way.

This is how SCSS has always worked. It really has nothing to do with the Angular CLI. The component’s CSS is being compiled by itself - the other files aren’t there. There’s no reason for them to be there.

This is not only how it works, this is how you should WANT it to work. You don’t want coupling with monolithic styles. You WANT each component to be a COMPONENT. They are isolated, encapsulated pieces of logic.

@JustasKuizinas if you want you can:

  • Ditch SASS and use css vars.

  • write a service that create css variables in style element in the head.

  • Get variables for the head style service from a js config

  • reuse same ts config in your template / ts code

  • When building your project with webpack use pure css with autoprefixer or

  • use the same approach as mentioned above with no variables for color / sizes configured if you van the benifits of the pre processor

More on this here: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables

As mentioned above this is not an angular issue but more of a seed (project base that use angular) issue (with all the build processes and pre-processing pre-dictated by the author).

Add this to .angular-cli.sjon (change includePath to your path):

"stylePreprocessorOptions": {
        "includePaths": [
          "../node_modules/bootstrap/scss/"
        ]
      },

Looks like we just need to duplicate in every component.

@import "~style/variables";

@AlexanderKozhevin Exactly. Just like you need to import anything you use in typescript you also need to import anything you use in SCSS.

My current solution is to turn off ViewEncapsulation for the component, but I dont like this at all. I wish there was a clean solution for this.

@Component({ selector: ‘app-admin’, templateUrl: ‘./admin.component.html’, encapsulation: ViewEncapsulation.None, styleUrls: [‘./admin.component.scss’] })

This is how SCSS has always worked. It really has nothing to do with the Angular CLI. The component’s CSS is being compiled by itself - the other files aren’t there. There’s no reason for them to be there.

This is not only how it works, this is how you should WANT it to work. You don’t want coupling with monolithic styles. You WANT each component to be a COMPONENT. They are isolated, encapsulated pieces of logic.

how does importing a static path fit to that cool isolation idea of yours? I call BS. Duplication of declarations is what really sucks. Thats why there are things like tree-shaking and module systems. But its not like i can create style modules (singletons) in angular which I can inject somewhere.

Well, there is this loader that could resolve all our problems - https://github.com/shakacode/sass-resources-loader I’ve been using it in one of the ejected projects, but will be nice if we could do this directly from CLI.

@ManuelGraf try this: @import ~src/variables in component.scss.

I prefer creating index.scss in the components folder (lets say you have a folder Search that lives under components). Then, import all the .scss files used in this folder into your newly created index.scss. Then, include @import "../components/Search/index"; in App.scss or wherever all your global partials are stored. Now all the .scss files inside components/Search will have access to global variables.

@dewwwald I think I figured out my problem. It turns out the elements that I was trying to access using these global variables were outside the scope of the main angular app. As my app is comprised of multiple modules, and apps it was not able to access these. I moved things around and am now able to have my components keep ViewEncapsulation on.