Setting Up Global Sass variables - css

I have a file called _colors.scss which has the following:
$base-vwhite: #ffffff;
$base-brand: #9ea70f;
This is imported in a file called utilities:
#import 'colors.scss';
I have a scss called components.scss which imports all the component styles:
#import 'menu.scss';
component.scss and utilities.scss are added to main.scss
#import 'utilities/utilities.scss';
#import 'components/components.scss';
My problem arises when the menu.scss tries to call a color variable:
.menu{
background-color: $base-brand;
}
I get the error:Undefined variable: "$base-brand;".
How do I need to set the colors variable so it can be used by all nested components and directories?

Related

SCSS Variable not applying globally

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
}

Sass outputs default file even with changed variables

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

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 to use $variables from one scss file to another

I'm working with Angular 4 application. Below is my code looks like.
variables.scss
$primary: blue;
$secondary: red;
Defining $variables.
styles.scss
#import './assets/variables';
Importing variables.scss file in styles.scss
angular-cli.json
"styles": [
"styles.scss"
]
Importing styles.scss file in angular-cli.json so that whatever the imports in styles.scss file can use my entire project.
header.html
<h1 class="primary-color">Header</h1>
Defined primary-color class in header.html file
header.scss
.primary-color{
color: $primary;
}
Trying to use $primary variable in header.scss file. But compiler throws me with error message as
Undefined variable: "$primary".
I tried to import variables.scss file in header.scss file and now it works fine as it displays text "Header" in blue color. Now my header.scss file looks like below.
header.scss
#import "~assets/variables.scss";
.primary-color{
color: $primary;
}
Now my questions is why should we import again in header.scss file though we already imported in styles.scss file? I don't like to import in every scss page because I've to use those $variables in so many scss files. Any thoughts/alternate-ideas please?

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