Separating sass files

I have this in _variables.scss

$hex-colors: (
	"foo": #dad,
	"bar": #be51de,
	"baz": #facade,
	"primary": #bad6e5
);

// Typography
$font-family-base: "Lato", 'Arial', sans-serif;
$font-size-base: 1rem;
$line-height-base: 1.6;

@import "~bootstrap/scss/functions";

@import "~bootstrap/scss/variables";

$theme-colors: map-merge($theme-colors, $hex-colors);

@import 'bootstrap/scss/bootstrap';

@import 'another-lib';
@import 'another-another-lib';
@import 'another-another-another-lib';
@import 'another-another-another-another-lib';

:root {
	--foo: #{$font-family-base};
	--bar: #{$font-size-base};
	//...
}
//...etc

I want to separate the files for variables and the imports, but this part

$theme-colors: map-merge($theme-colors, $hex-colors);

prevents me from having a clean all-variables and imports files. It needs to be after these two imports @import "~bootstrap/scss/functions" and @import "~bootstrap/scss/variables". How can I resolve this? Is it advisable to separate the two at all?

I dont… understand this line.

The thing that you have highlighted is… a variable declaration. The same as the $font-family-base declaration before it. What do you mean by “a clean all-variables and imports files”?

Sorry for being unclear.

I’m trying to separate them like this:

//_variables.scss
$hex-colors: (
	"foo": #dad,
	"bar": #be51de,
	"baz": #facade,
	"primary": #bad6e5
);
$theme-colors: map-merge($theme-colors, $hex-colors);

$font-family-base: "Lato", 'Arial', sans-serif;
$font-size-base: 1rem;
$line-height-base: 1.6;


:root {
	--foo: #{$font-family-base};
	--bar: #{$font-size-base};
	//...
}
//_imports.scss

@import "variables";
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import '~bootstrap/scss/bootstrap';
@import 'another-lib';
@import 'another-another-lib';
@import 'another-another-another-lib';
@import 'another-another-another-another-lib';

Clearly, I can’t do this because it’s throwing an error:

SassError: Undefined variable.
   â•·
29 │ $theme-colors: map-merge($theme-colors, $hex-colors);
   │                          ^^^^^^^^^^^^^
   ╵

Maybe wrapping the needed variables for bootstrap instead like this

@function bs-colors {
	$hex-colors: (
	"foo": #dad,
	"bar": #be51de,
	"baz": #facade,
	"primary": #bad6e5
);
	$theme-colors: map-merge($theme-colors, $hex-colors);
}

so I’ll only call the function in _imports.scss like this

@import "variables";
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
//-- call the function here
@import '~bootstrap/scss/bootstrap';

I can’t place them above or at the bottom because it doesn’t work, the colors are not applied.

//-- vars are not applied here
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import '~bootstrap/scss/bootstrap';
//-- vars are not applied here

It’s possible to import the file in the middle

// -- imports.scss
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "variables";
@import '~bootstrap/scss/bootstrap';

But I don’t know, it still feels wrong because even the non-bootstrap-related variables would be included in the middle.

I mean…if you’ve got site-specific variables, being overlaid on default variables, you’re going to have to import both eventually.

You would obviously need to import the defaults first, then the site-specific. That’s just how overlaying works.

If you’re concerned about mixing bootstrap and non-bootstrap site-specific variables…separate your bootstrap and non-bootstrap site-specific variables, and import them as relevant?

I don’t know sass, but from the looks of this error, it’s not because of the multiple files thing - it’s because you haven’t declared $theme-colors

As a test, add this line right above that line:

$theme-colors: (
	"light": #fff,
	"dark": #000
);

I believe the implication is that $theme-colors is coming from inside @import "~bootstrap/scss/variables";

Agreed, but his _variables.scss is what is throwing the error.

//_variables.scss
$hex-colors: (
	"foo": #dad,
	"bar": #be51de,
	"baz": #facade,
	"primary": #bad6e5
);
$theme-colors: map-merge($theme-colors, $hex-colors);

Seems to me something called a map-merge would need an initialized variable to merge in.

I just tested this in codepen, and it seems to agree with me. This does not throw any errors (his version does), so it needs an initialized variable to map…

//_variables.scss
$hex-colors: (
	"foo": #dad,
	"bar": #be51de,
	"baz": #facade,
	"primary": #bad6e5
);
$theme-colors: (
	"light": #fff,
	"dark": #000
);
$theme-colors: map-merge($theme-colors, $hex-colors);

Right… and that’s why he said that this one works:

// -- imports.scss
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables"; <-- Default Loaded here.
@import "variables"; <-- Map merge happens here.
@import '~bootstrap/scss/bootstrap';

because it loaded the default $theme-colors first from the bootstrap variables, then map-merged.

@import in scss files acts like include does in PHP - in effect, it acts as if you’d copied and pasted the file’s contents at that point.

1 Like