Solution 1:

It's one of those things that's just not allowed. The only thing you can do is turn those imports into mixins (import the file outside the @if and call the mixin where appropriate).

Clarification:

_partial.scss

@mixin partial {
    .test { color: red }
    // other styles here
}

styles.scss

@import "partial";
@if $someval == true {
    @include partial;
}

Solution 2:

The core dev team is reluctant to implement this feature, although they are considering the implementation of a brand new dependency system.


See the following Github issues :

  • Allow @import within @if (#451)
  • Using @import statements within control directives or mixins (#779)
  • Allow optional @imports (#779)
  • Dynamic Dependencies (#739)

Solution 3:

Put your styles into various partial files in a way that makes sense to you. Then, you can have create a separate SASS file for your login page that imports only the files with the relevant styles.

To quote from my answer to another question:

It is currently not possible to use SASS to include files dynamically. @import cannot be used within control directives (e.g. @if) or mixins, using a variable in an import directive is erroneous syntax, and there is no directive for ending file execution early (which effectively would allow conditional imports). However, you can solve your issue by changing how you structure your style rules.

... If you have styles that [should be] conditionally included [they] should be encapsulated in mixins, in 'module' or 'library' files. ... The main idea is that importing one such file will not output any css. This way, you can import these files redundantly so you can use the mixins wherever you need them.

Solution 4:

There isn't currently a way to place import statements within if blocks, unfortunately.

The closest alternative I'm aware of is to use the additionalData field to add a preprocessor function to your webpack sass-loader config:

{
    loader: "sass-loader",
    options: {
        sassOptions: {
            includePaths: [...],
        },
        additionalData: (content: string, loaderContext)=>{
            // More info on available properties: https://webpack.js.org/api/loaders
            const {resourcePath, rootContext} = loaderContext;
            
            const finalPath = someCondition ? path1 : path2;
            return content.replace(/SomeDynamicPathPlaceholder/g, finalPath);
        },
    },
},

More info on the additionalData field here: https://webpack.js.org/loaders/sass-loader/#additionaldata

Solution 5:

I know this is a seriously old question, but we recently implemented this in our own tiny UI framework like this:

ui-framework/config.scss

$components: (
    "component-a": true,
    "component-b": false
) !default;

// A bunch of other default config

ui-framework/main.scss

@import "component-a";
@import "component-b";

ui-framework/component-a.scss

@if (map-get($components, "component-a") {
    .component-a {
        // Bunch of code here
    }
}

ui-framework/component-b.scss

@if (map-get($components, "component-b") {
    .component-b {
        // Bunch of code here
    }
}

And then in each project:

a-project/main.scss

// NOTE: We only want component b in this project
$components: (
    "component-a": false,
    "component-b": true
);

@import "ui-framework/config.scss";
@import "ui-frameowrk/main.scss";

We don't do this for every single component, but the huge ones that aren't always in use (like slideshow, dialog, form related code etc).