SCSS Variable not applying globally - css

I have a variable and gallery partial: _variables.scss, _gallery.scss
When I import the variables file, which contains only one line $primary: #e0291a;, it works in the main style.scss file, but not in the _gallery.scss file.
My project is only going to grow, but do I really need to import the variables file in every single subsequent partial file?
I'm using VSCode Live Sass Compiler. The variables work with a custom webpack/laravel mix script I've set up a few years back, but not with this extension.
Is there a way to streamline the variable import without adding the line in every single scss file?
style.scss (main file):
#use 'variables';
#use 'gallery';
_variables.scss:
$primary: #ffffff;
_gallery.scss:
#gallery {
background-color: $primary // <--- Throws error of undefined variable
}

Related

import CSS variable not recognized

I have an angular (8.2.12) project that has a css file that defines a lot of styling variables, named _vars.scss and it is placed in the ClientApp\src\scss\ folder. Some variables defined in that file are as below:
// NAVBAR
$nav-font-color: black;
$nav-bg-color: white;
These styling variables are used by the nav-menu.component in the ClientApp\src\app\nav-menu\nav-menu.component.css via the #import statement as below:
#import '../../scss/_vars.scss';
There are two problems:
It complains about the comment // NAVBAR, saying it is invalid, so I have to remove those comment line from that file
None of the $nav-xxx variables are recognized in the nav-menu.component.css file, e.g.
.navbar { background: $nav-bg-color; <-- here it complains 'Property value expected', which means the value of that variable was not imported in correctly. }

Multiple scss Files Referencing One Main Style File

I'm working on a React app and have three scss files, one being the main file that contains theme variable colors, while the other 2 are part of its' component folder.
Let's say I import main into the contacForm styles.css and apply the variable color. Things work as expected. BUT as soon as I import main into keepInTouchForm styles.scss, it removes the styling from contactForm
Question is why is this happening and what is the correct way to keep one main.scss file with all variables and reference across multiple scss files?
Here's my folder structure:
- components
-- contactForm
--- index.js
--- styles.scss
-- keepInTouchForm
--- index.js
--- styles.scss
- scss
-- main.scss
main.scss has the following code:
$theme-colors: (
'primary': #00a677,
'secondary': #dde1e7,
);
styles.scss inside contactForm folder code:
#import '../../scss/main.scss';
.form-control {
border: 1px solid theme-color('secondary');
}
styles.scss inside keepInTouchForm folder code:
#import '../../scss/main.scss'; //breaks the above code
map-get syntax seems to work well for me.
map-get($theme-colors, primary);

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.

"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;
}

SASS - use variables across multiple files

I would like to keep one central .scss file that stores all SASS variable definitions for a project.
// _master.scss
$accent: #6D87A7;
$error: #811702;
$warning: #F9E055;
$valid: #038144;
// etc...
The project will have a large number of CSS files, due to its nature. It is important that I declare all project-wide style variables in one location.
Is there a way to do this in SCSS?
You can do it like this:
I have a folder named utilities and inside that I have a file named _variables.scss
in that file i declare variables like so:
$black: #000;
$white: #fff;
then I have the style.scss file in which i import all of my other scss files like this:
// Utilities
#import "utilities/variables";
// Base Rules
#import "base/normalize";
#import "base/global";
then, within any of the files I have imported, I should be able to access the variables I have declared.
Just make sure you import the variable file before any of the others you would like to use it in.
This question was asked a long time ago so I thought I'd post an updated answer.
You should now avoid using #import. Taken from the docs:
Sass will gradually phase it out over the next few years, and
eventually remove it from the language entirely. Prefer the #use rule
instead.
A full list of reasons can be found here
You should now use #use as shown below:
_variables.scss
$text-colour: #262626;
_otherFile.scss
#use 'variables'; // Path to _variables.scss Notice how we don't include the underscore or file extension
body {
// namespace.$variable-name
// namespace is just the last component of its URL without a file extension
color: variables.$text-colour;
}
You can also create an alias for the namespace:
_otherFile.scss
#use 'variables' as v;
body {
// alias.$variable-name
color: v.$text-colour;
}
EDIT As pointed out by #und3rdg at the time of writing (November 2020) #use is currently only available for Dart Sass and not LibSass (now deprecated) or Ruby Sass. See https://sass-lang.com/documentation/at-rules/use for the latest compatibility
This answer shows how I ended up using this and the additional pitfalls I hit.
I made a master SCSS file. This file must have an underscore at the beginning for it to be imported:
// assets/_master.scss
$accent: #6D87A7;
$error: #811702;
Then, in the header of all of my other .SCSS files, I import the master:
// When importing the master, you leave out the underscore, and it
// will look for a file with the underscore. This prevents the SCSS
// compiler from generating a CSS file from it.
#import "assets/master";
// Then do the rest of my CSS afterwards:
.text { color: $accent; }
IMPORTANT
Do not include anything but variables, function declarations and other SASS features in your _master.scss file. If you include actual CSS, it will duplicate this CSS across every file you import the master into.
In angular v10 I did something like this, first created a master.scss file and included the following variables:
master.scss file:
$theme: blue;
$button_color: red;
$label_color: gray;
Then I imported the master.scss file in my style.scss at the top:
style.scss file:
#use './master' as m;
Make sure you import the master.scss at the top.
m is an alias for the namespace;
Use #use instead of #import according to the official docs below:
https://sass-lang.com/documentation/at-rules/import
Then in your styles.scss file you can use any variable which is defined in master.scss like below:
someClass {
backgroud-color: m.$theme;
color: m.$button_color;
}
Hope it 'll help...
Happy Coding :)
Create an index.scss and there you can import all file structure you have. I will paste you my index from an enterprise project, maybe it will help other how to structure files in css:
#import 'base/_reset';
#import 'helpers/_variables';
#import 'helpers/_mixins';
#import 'helpers/_functions';
#import 'helpers/_helpers';
#import 'helpers/_placeholders';
#import 'base/_typography';
#import 'pages/_versions';
#import 'pages/_recording';
#import 'pages/_lists';
#import 'pages/_global';
#import 'forms/_buttons';
#import 'forms/_inputs';
#import 'forms/_validators';
#import 'forms/_fieldsets';
#import 'sections/_header';
#import 'sections/_navigation';
#import 'sections/_sidebar-a';
#import 'sections/_sidebar-b';
#import 'sections/_footer';
#import 'vendors/_ui-grid';
#import 'components/_modals';
#import 'components/_tooltip';
#import 'components/_tables';
#import 'components/_datepickers';
And you can watch them with gulp/grunt/webpack etc, like:
gulpfile.js
// SASS Task
var gulp = require('gulp');
var sass = require('gulp-sass');
//var concat = require('gulp-concat');
var uglifycss = require('gulp-uglifycss');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('styles', function(){
return gulp
.src('sass/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(concat('styles.css'))
.pipe(uglifycss({
"maxLineLen": 80,
"uglyComments": true
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./build/css/'));
});
gulp.task('watch', function () {
gulp.watch('sass/**/*.scss', ['styles']);
});
gulp.task('default', ['watch']);
As previously mentioned, the use of #import is discouraged in newer versions of SASS. Use #use "path to SASS partial file" at the top of your file instead.*
You need to import (using #use) the partial SASS file into each SASS file that uses it - not just your main one.
Let's say we have a SASS file called _variables.scss* in a folder called partials that we want to use in header.scss. So in header.scss you write:
#use "partials/variables" as *
Now you can use all the variables defined in _variables.scss* with $variable (no prefix). Alternatively, you can use a namespace (like Christian already mentioned)
#use "partials/variables" as v
to refer to the variables inside _variables.scss* with v.$variable.
* Note that the SASS compiler ignores underscores so that there isn't a separate CSS file generated for each partial SASS file. Instead you can just import them all into your main SASS file with #use.
How about writing some color-based class in a global sass file, thus we don't need to care where variables are. Just like the following:
// base.scss
#import "./_variables.scss";
.background-color{
background: $bg-color;
}
and then, we can use the background-color class in any file.
My point is that I don't need to import variable.scss in any file, just use it.
I found a solution for vue3 using vite. If you are using dart-sass, you can get around the global limitation of sass modules by using #forward and #use.
_master.scss
$accent: #6D87A7;
$error: #811702;
$warning: #F9E055;
$valid: #038144;
// etc...
_global.scss
#forward '_master.scss';
// etc...
Then under the vite.config.js configure your css options as
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `
#use "./<path-to-file>/_globals.scss" as *;
`,
},
},
},
// etc...
});
As mentioned in the sass docs when importing modules without a namespace
We recommend you only do this for stylesheets written by you, though; otherwise, they may introduce new members that cause name conflicts!
You can then use other #use modules in any other stylesheets or components as following
// component file needing a function module
#use 'functions.scss';

Resources