ChatGPT解决这个技术问题 Extra ChatGPT

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?

I am pretty sure that is not possible, I tried the same thing awhile ago and could not get it to work.
@DrCord on the contrary it is a central feature of SASS: sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#partials
Sweet! I think I may have misread this statement: "Directives that are only allowed at the base level of a document, like mixin or charset, are not allowed in files that are imported in a nested context." and not properly read the "nested context" part.

d
dthree

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.


Perfect. Just what I meant and needed. Last question: Are all files imported expected to start with an underscore? You underscore your file name, but fail to on the @import declarations.
those files are considered partial files and the names have to start with underscores, you leave it out when importing it though. there is a really good article that details why here: alistapart.com/article/getting-started-with-sass
Note that you can declare defaults inside your modules: $black: #000 !default;. The !default thingie prevents the variable from being reset if it already exists.
Why we have to dump all the variables in a single file? Can't we split and drop them in the respective file that needs them? For example the variables needed for modal dialog can't we place them in _modal.scss?
This answer is no longer the recommended way to re-use variables across multiple files. Please see stackoverflow.com/a/61500282/7513192
w
whiscode

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 should be now the selected answer, since "import" is marked as deprecated and will be removed in the future.
This is true only for dart-sass that is way less performant than libsass.
@und3rdg I've updated the post to reflect this compatibility point. It's worth mentioning that libsass is now deprecated There is a comment on the github page advising people to use Dart Sass instead for future projects - github.com/sass/libsass
It's an interesting change which actually changes things quite a bit, meaning when using partials you have to @use the variables as those variables are no longer globally available.
@whiscode yes, you are right :,( LibSass is dead, long live the DartSass! - sass-lang.com/blog/libsass-is-deprecated
d
dthree

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.


Thanks so much for your comment about the file needing to start with an underscore! I just spent about 3 hours trying to figure out why I was missing a bunch of Foundation styles. Changed the filename of my Foundation settings file to start with an underscore and hey presto! But now when I change the filename back again, it's still working? What the....? Oh well... Sighs and accepts it's now working
Don't change it back - it's probably 'working' off some generated CSS from your SCSS file when it was working. Just use the underscore. But otherwise, great on getting it working!
@poshaughnessy it might work because sass uses cache, so it could be cached. Not 100% sure through.
same for sass??
Correct you are @rinogo.
C
Cristian

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 :)


C
Carnaru Valentin

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']);

Aren't you supposed to omit the underscore from @import statements?
Sass '@import' works either way. you can write the URI with or without the underscore. also with or without the '.scss' ending.
p
princess_hacker

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.


r
robere2

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.


Obvious is a bad idea, you can have many variables and is more clean to keep index with just imports, and every file to have is own propose.
T
Tyler Hartleb

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