Split up theme SCSS into multiple files

Themes and theme components are becoming steadily more powerful, and developers are getting more and more ambitious. To make things easier for developers, themes can now split their SCSS into multiple files.

When creating a new theme with the theme CLI, or sharing a theme on github, simply create a new folder called scss. Fill it with your .scss files, following any folder structure, and all the files will be available for you to import in the common / desktop / mobile SCSS sections of your theme.

For example, if you want to have a common variable available to both mobile and desktop SCSS, you could do something like this:

scss/myfolder/variables.scss

$favourite-color = red;

desktop/desktop.scss

@import "myfolder/variables";
body {
  background-color: $favourite-color;
}

mobile/mobile.scss

@import "myfolder/variables";
body {
  color: $favourite-color;
}

This feature was added in v2.3.0.beta8, so do not use these features quite yet if you need to maintain backwards compatibility with older versions of Discourse. You can use the minimum_discourse_version parameter of about.json to ensure your component doesn’t get used on an earlier version.

19 Likes

This is amazing @david! Nice work!

I can’t wait to give this a whirl.

8 Likes

This is a great! I can now remove my hack for getting around not being able to do this.

5 Likes

@david this is great, but unfortunately it doesn’t seem to work when the theme is a component. Not sure if that’s a known bug.

You can see it happen with this very simple theme: https://github.com/LeoMcA/discourse-multi-scss-component

When converted to a stand-alone theme the background colour will be green, but when used as a component within another theme it doesn’t change the background colour at all.

5 Likes

Thanks @LeoMcA, you’re right - this wasn’t working in components. The issue should be fixed in

https://github.com/discourse/discourse/commit/933d2798113c2a54264cf927fc8eabe660bfd17a

4 Likes

Is that still supposed to work? My default scss files (common/desktop/mobile) don’t work when I add an @import.

Or is there a new recommendation for splitting files?

This should still work. Can you share the precise @import statement you’re using, and the file structure of your stylesheets?

The theme setup has default file structure and I added scss/test.scss Then I state @import "test";

On the console (using discourse_theme watch) I get:
✘ Error in common scss: Error: File to import not found or unreadable: test. on line 1 of common.scss

Does your test.scss file have any content?

Just declared one variable (btw there’s a typo on the first code block above, declared with equals: $favourite-color = red;)

But just solved it. I set the minimum version in about.json as v2.3.0.beta8 and when I remove that, it works just fine. Never used that before, so not sure what’s wrong with the declaration.

1 Like

Interesting! If you add the minimum version again, does it consistently break? If so, would you mind zipping up the broken theme and sharing it here? (or PMing it to me)

1 Like

As said, I never set a min version before. So I just copied it above as v2.3.0.beta8. This breaks, but 2.3.0.beta8 works just fine.

Is it possible to use scss files from a node_modules package? For example:

@import 'bootstrap/scss/bootstrap.scss';
@import '../node_modules/bootstrap/scss/bootstrap.scss';

In both cases I can’t import this from /scss folder.