Sass outputs default file even with changed variables - css

I'm trying to change some variables for my custom version of Bootstrap. Right now I have the Bootstrap SCSS files and my own variables file. My file looks like this:
#import "/path/to/bootstrap";
$blue: #42a5f5;
$indigo: #5c6bc0;
more styles here…
However, when I run sass /path/to/custom.scss /path/to/output.css, it still outputs the default Bootstrap files like this:
:root {
--blue: #007bff;
--indigo: #6610f2;
more styles here…
Why does this happen?

According to Bootstrap 4:
Variable overrides within the same Sass file can come before or after the default variables. However, when overriding across Sass files, your overrides must come before you import Bootstrap’s Sass files.
Since you create your own custom.scss file, it should look like this:
// Your variable overrides
$blue: #42a5f5;
$indigo: #5c6bc0;
// Bootstrap and its default variables
#import "/path/to/bootstrap";

Related

Can I use variables across SCSS files?

I'm using different 'SCSS variables files' (bootstrap variables, company variables, project variables) so it's easy to re-use them in other projects. But it seems I can't use variables across files.
Example:
In company-variables.scss I declared $white: #fff;
In project-variables.scss I want to reuse the above variable like this $body-color: darken($white, 20%);
I get the following error: Undefined variables: "$white". $body-color: darken($white, 20%);
I load my files like this:
#import "bootstrap-variables";
#import "company-variables";
#import "project-variables";
Paths are correct.
I'm pretty new to SCSS. Any idea what I'm doing wrong or is this not possible/not the way to go?
If you want to use it , you should import #import "company-variables"; into #import "project-variables";
Or just use default white color from bootstrap like that:
darken(theme-color("white"), 20%);

Conditially override scss variables for bootstrap 4 theme switching

Per the Bootstrap docs,
Every Sass variable in Bootstrap 4 includes the !default flag allowing
you to override the variable’s default value in your own Sass without
modifying Bootstrap’s source code. Copy and paste variables as needed,
modify their values, and remove the !default flag. If a variable has
already been assigned, then it won’t be re-assigned by the default
values in Bootstrap.
So they recommend you create your own theme like this:
// Your variable overrides
$body-bg: #000;
$body-color: #111;
// Bootstrap and its default variables
#import "node_modules/bootstrap/scss/bootstrap";
What I would like to do is have two sets of variables, and uses this to switch between a light and dark theme:
// Your variable overrides
body.light-mode {
$body-bg: #fff;
}
body.dark-mode {
$body-bg: #000;
}
// Bootstrap and its default variables
#import "node_modules/bootstrap/scss/bootstrap";
But this doesn't seem to be working, I think because of how variables are scoped.
Is this possible? Ideally I'd like to have light and dark variables in their own file.
For a little context; I am using bootstrap in a web app created by create-react-app, and they recommend to import bootstrap as detailed here. If I just generated 2 separate style sheets I'd have copy those to my /public folder manually and reference, and they wouldn't be part of the webpack bundling.
This was the solution I went with:
// Default theme
$body-bg: #fff;
// etc...
// Bootstrap and its default variables
#import "node_modules/bootstrap/scss/bootstrap";
// dark theme, turned on by adding class dark to document.documentElement (html tag)
.dark {
$body-bg: #000;
// etc...
// Import just the things you customize
#import "~bootstrap/scss/functions";
#import "~bootstrap/scss/variables";
#import "~bootstrap/scss/mixins";
#import "~bootstrap/scss/tables";
#import "~bootstrap/scss/button-group"
// etc....
}
That won't work. Why not make two different themes - dark/light:
light theme (light-theme.scss):
// Your variable overrides
$body-bg: #fff;
// Bootstrap and its default variables
#import "node_modules/bootstrap/scss/bootstrap";
dark theme (dark-theme.scss):
// Your variable overrides
$body-bg: #000;
// Bootstrap and its default variables
#import "node_modules/bootstrap/scss/bootstrap";
and then pull the appropriate style sheet into the page as needed?

How do I compile my .scss file into multiple .css files depending on the variables

I have a simple gulp build to compile my .scss files:
gulpfile.js:
gulp.task('sass', function() {
return gulp.src('app/assets/scss/**/*.scss')
.pipe(gulp.dest('app/assets/css'))
});
...
index.scss:
$brand-primary: #b0b0b0;
// $brand-primary: #b1b1b1;
// $brand-primary: #b2b2b2;
...
In index.scss I have multiple versions of the $brand-primary variable I want the file to compile with, e.g. I want gulpfile.js to automatically create multiple versions of index.scss depending on the $brand-primary variable: index-1.css, index-2.css, index-3.css, etc. with the $brand-primary value equal to #b0b0b0 first, then #b1b1b1, then #b2b2b2 accordingly.
The idea is to create multiple color options for my template without manually recompiling it for each color.
PS: I am aware of CSS variables, however those won't work with color function like darken($brand-primary, 10%);
It would be very hard to do what you ask purely programatically. I'm not even sure it's possible.
Why don't you just create 3 index.scss files each with different $brand-color and and then import everything else in them. Or even better make another file which will import all of your other *.scss files and then just import that file and color in each index file. So your index files would look like this:
$brand-primary: #b0b0b0;
#import 'style';
and _style.scss would have all of your other scss dependencies.

How to override scss variables?

I am currently using materialize.css and I want to override the default variables so that the main file remain unchanged. What I am trying in my main stylesheet.scss is like
#import '_materialize';
#import '_modified';
#import '_new';
In my _modified file I am setting
$secondary-color: color("blue", "darken-1");
In materialize.scss, _variable.scss is already imported (default framework file) in which secondary color value is
$secondary-color: color("teal", "lighten-1") !default;
Still secondary color remain teal.How to override with external scss file like this one?
Edit-1: Found the solution.
$secondary-color: color("teal", "lighten-1") !default;
was not working due to not loading color mixin file of materialize css.
After #import "materialize/components/color"; in modified.scss and then
$secondary-color:color("teal", "lighten-5");
works now.
Import your vars first (not last):
#import '_your-vars'; // your own vars
#import '_materialize'; // includes framework vars
... // other modifications
As far as I understand the SCSS !default flag: it's a fallback, when nothing has been declared before. So when you import your variables (only the variables, no other modifications which might have dependencies) first, it will work.
See below examples
$secondary-color: color("blue", "darken-1");
.someClass{
$secondary-color: color("teal", "darken-1") !important;
.someClass h2{
color: $secondary-color;
}
}

"lessify" a CSS color theme

I've inherited a project with a ton of CSS and been assigned the task of modifying it so the color palette can easily be changed.
I've immediately thought of using a CSS preprocessor, tried less and easily switched the colors for variables, so I just have to define a base color and can switch the color theme.
The problem is, every time I switch the color theme I have to either overwrite colors.less with the new color settings or modify the colors.less import in a ton of files.
What I want is to end up with a single file with a lot of imports (basically one per component or set of components), and on that file when I import colors-red.less instead of colors-blue.less all the components imported right after use the red palette so the theme compiled is red instead of blue, for example.
The problem I am having is that the component files do not get the "globals" with the color definitions so I can't compile the base file that imports those files.
I've read there is the possibility of using "partials" (files starting with _ that won't get compiled independently but imported and then compiled), but my compiler seems to be ignoring this feature, and the eclipse plugin I use for editing and verifying less files also complains about the color variables not being defined on those partials.
How can I can get the partials to work? Is there a better approach to do this task?
Stil, they won't be defined on the imported files, just on the main file, so >compilation will break on the imported files. You see what I mean?
Nope? example:
mixins.less:
.mixin()
{
color: #color;
}
variables.less:
#color: orange;
project.less:
#import "mixins";
#import "variables";
p {
.mixin();
}
Now running lessc project.less outputs:
p {
color:orange;
}
Now i change to content of project.less as follows:
#import "mixins";
#import "variables";
p {
.mixin();
}
#color: red;
Then running lessc project.less outputs:
p {
color:red;
}

Resources