I'm working on a new Angular2 project built using Angular CLI and have configured the project to use SCSS. I have Bootstrap 4 successfully loaded into my styles.scss
file however if I try and access any of Bootstrap's (or my own variables defined in styles.scss
from within a component I get Undefined Variable
build error.
Are the style files for components compiled before the main entry in the styles
node of angular-cli.json
? How can I make is so that any variables defined at that global level are available to all components in the application? Thanks!
angular-cli.json
"apps": [
{
...
"styles": [
"styles/styles.scss"
],
...
}
]
styles.scss
// Bootstrap
$enable-flex: true; // Enable Flexbox mode
@import "../../node_modules/bootstrap/scss/bootstrap";
component
.navbar {
background: $brand-primary; // Undefined variable here
}
Just because you are importing the bootstrap 4 into your styles.scss
doesn't mean your .scss
files on your components have access to that.
On your component.scss
you have to import the Bootstrap variables:
@import '~bootstrap/scss/_variables.scss';
.navbar {
background: $brand-primary; // No more Undefined variable here
}
Explanation
A lot of people seem to me confused by this, you should not import bootstrap.scss
to your components you should only import the things that you need.
If you look closely into the source code of bootstrap.scss they have everything separated in different files. You have the mixins
folder and the _variables.scss
file. Those should be the only things you import on your component to avoid CSS duplication.
Would this increase my bundle size, importing these things on every component?
No, it won't. Why? mixins
and variables
are sass specific (at least for now) so when you import all the variables into your component like this:
@import '~bootstrap/scss/_variables.scss';
.navbar {
background: $brand-primary;
}
the output CSS of that will be:
.navbar {
background: #007bff;
}
The rest of the variables will be discarded after compiling to CSS.
Create a _colors.scss file, copy all the color variables inside and import that file in your component.scss file.
A few people have suggested @import
-ing the variables.scss
in every component .scss
but I found this a little messy. Doing so did not also work well with the way our company CSS is architectured. I ended up going in this direction to enable me to use the variables, mixins, and also extend styles. This also allows me to manage all of the CSS in one location.
I'm currently working on a project that has been generated by Angular2 CLI. So there is a main style.scss
Another way I was able to accomplish this is by doing the following:
Removing the styleUrls
from the app.component.ts
files.
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
// styleUrls: ['./app.component.scss']
});
I manage all the less files in the main styles.scss
. So my current setup looks something like:
// Bootstrap
@import "../node_modules/bootstrap-less/bootstrap/index";
// Company Branding
@import "theme/index";
// Components
@import "app/app.component.scss";
@import "app/search/search.component.scss";
Hopefully this alternative solution will be helpful to someone.