【问题标题】:@import in @if statement in SassSass 中的 @if 语句中的 @import
【发布时间】:2012-12-02 11:25:22
【问题描述】:

我只想加载登录页面所需的 css 以提高性能。在我的其他页面上,我想要一个分组的 css 文件,该文件将缓存在包含我所有 css 的每个页面上。

我有以下文件:

minifiedcssforloginpage.scss
grouped-pages.scss

在 minifiedcssforloginpage.scss 我声明 $load-complete-css:false。之后我导入 myproject.scss ,其中包含我的模块、布局、核心的所有导入......在 myproject.scss 我想做类似的事情

@if $load-complete-css {
     @import module1;
     @import module2;
     @import module3;
}

因此,minifiedcssforloginpage.scss 会生成 minifiedcssforloginpage.css,其 css 少于 grouped-pages.css(将 var $load-complete-css 设置为 true)。

但我得到一个错误,这是不可能的“导入指令可能不能在控制指令或混合中使用”。

【问题讨论】:

  • 不过,您确实明白,SASS 不是动态的,对吧?编译好之后就可以了。没有状态变化或类似的东西。用户登录后,您不能将 $loggedin 设置为 true,因为 CSS 已经编译。
  • 是的,这是一个糟糕的命名。我改了

标签: if-statement import sass dependencies mixins


【解决方案1】:

这是不允许的事情之一。您唯一能做的就是将这些导入转换为 mixin(将文件导入到 @if 之外并在适当的地方调用 mixin)。

澄清:

_partial.scss

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

styles.scss

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

【讨论】:

  • 你的意思是像@if $load-complete-css { @include othercomponents; } @mixin othercomponents { @import "module1" ; @import "modules2"; }?我现在有同样的错误.. 也不可能在 mixin 中导入
  • 正确:有问题的 mixin 也无法执行导入。如果您想与@if 一起使用,您必须将文件的全部内容放入单个mixin。
  • 一页独有的样式有多少?拆分文件并引发 2 个 HTTP 请求可能比拥有一个包含所有内容的文件更糟糕。
  • @cimmanon 或者不是。较小的文件可以独立缓存。如果一个或另一个文件将被缓存以供将来的页面加载,则两个 HTTP 请求是没有问题的。我倾向于认为,当前为整个站点连接所有 CSS 和 JS 的时尚是非常糟糕的做法,这是由于未能考虑如何正确模块化造成的。
  • 我对这个解决方案非常感兴趣——非常聪明的想法谢谢!
【解决方案2】:

以对您有意义的方式将您的样式放入各种partial 文件中。然后,您可以为您的登录页面创建一个单独的 SASS 文件,该文件只导入具有相关样式的文件。

my answer引用另一个问题:

目前无法使用 SASS 动态包含文件。 @import 不能在控制指令中使用(例如 @if)或 mixins,在导入指令中使用变量是错误的语法, 并且没有提前结束文件执行的指令(其中 effectively 将允许有条件的导入)。但是,您可以 通过更改样式规则的结构来解决您的问题。

...如果您有 [应该] 有条件地包含的样式 [它们] 应该封装在 mixins 中,在“模块”或“库”文件中。 ... 主要思想是导入一个这样的文件不会输出任何 CSS。这样,您可以冗余地导入这些文件,以便您可以使用 任何你需要的 mixin。

【讨论】:

    【解决方案3】:

    核心开发团队不愿实施此功能,尽管他们正在考虑实施全新的依赖系统。


    查看以下 Github 问题:

    【讨论】:

    • 你知道他们为什么不情愿吗?这个功能现在对我非常有帮助。
    • @thephpdev :您可能想看看@Github 上正在进行的讨论并为讨论做出贡献(请参阅上面的链接)。请求此功能的人越多,他们最终实现它的可能性就越大;-)
    • 是的,我做到了。这就是“最终”的关键。可能不会发生。我看到了他们构建某种新的依赖管理系统的一些事情。但那是三年前的事了。看起来并没有真正发生任何事情。所以我只是没有真正看到这一点。 :)
    • @thephpdev : 他们无法与用户的实际需求联系起来,并且不愿意实现像动态依赖这样重要的功能,这一直困扰着我很长时间,以至于我实际上考虑编写我的自己的预处理器语言......这很糟糕,但我想如果我们想继续使用 Sass,我们只能忍受......
    • 确实如此。还是喜欢它而不是纯 CSS,虽然哈哈。
    【解决方案4】:

    不幸的是,目前没有办法将 import 语句放在 if 块中。

    我知道的最接近的替代方法是使用 additionalData 字段向您的 webpack sass-loader 配置添加预处理器函数:

    {
        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);
            },
        },
    },
    

    有关additionalData 字段的更多信息:https://webpack.js.org/loaders/sass-loader/#additionaldata

    【讨论】:

      【解决方案5】:

      我知道这是一个非常古老的问题,但我们最近在我们自己的微型 UI 框架中实现了这个,如下所示:

      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
          }
      }
      

      然后在每个项目中:

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

      我们不会对每个单独的组件都这样做,但并不总是在使用的大型组件(如幻灯片、对话框、表单相关代码等)。

      【讨论】:

        【解决方案6】:

        老问题,我知道;只是觉得我会根据我正在做的事情提供一个替代方案和扩展示例。

        我遇到了这个问题,因为我希望将一个 SCSS 文件用于较小的屏幕,而将一个 SCSS 文件用于较大的屏幕(桌面上的顶部菜单导航和移动设备上的汉堡菜单)。

        在没有 Bootstrap 的情况下使用 Blazor,我想根据实际 html 使用一个菜单结构,然后使用 SCSS 在相关大小的两者之间切换。我为导航的桌面版本创建了一个 SCSS 文件,并开始为移动版本创建一个。在我意识到这个绊脚石之前,我的计划是根据 mixin 中的媒体查询(恰当地命名为 mobileOrDesktop)有选择地导入 SCSS。

        我的想法是使用这个 mixin 来对媒体大小进行所有基本结构操作。像这样的:

        @mixin mobileOrDesktop {
            @media (min-width: 961px) {
                @import 'desktopNavbar.scss';
        
                .container-fluid {
                    margin-top: 70px;
                    height: calc(100% - calc(60px + 70px));
                }
        
                //show the footer, maybe tweak the font size, etc
            }
        
            @media (max-width:960px) {
                @import 'moblieNavbar.scss';
        
                .container-fluid {
                    height: 100%;
                }
                //hide the footer, maybe tweak font sizes, etc
            }
        }
        

        很遗憾,由于 SCSS 的工作原理,我们无法做到这一点。因此,我不只是在媒体查询中转储所有 CSS(我想让它相对分开,以便调试/更改更易于管理),而是寻找替代方案。

        与 Cinnamon 类似,我发现最可行的解决方案是在 mixin 之外导入 SCSS,然后将其简单地包含在 mixin 中:

        @import 'desktopNavbar.scss';
        @import 'mobileNavbar.scss';
        
        @mixin mobileOrDesktop {
            @media (min-width: 961px) {
                @include desktopNavbar;
        
                .container-fluid {
                    margin-top: 70px;
                    height: calc(100% - calc(60px + 70px));
                }
            }
        
            @media (max-width:960px) {
                @include moblieNavbar;
        
                .container-fluid {
                    height: 100%;
                }
            }
        }
        

        导入的 SCSS 文件本身就是一个 mixin,即 desktopNavbar.scss 变为:

        @import 'siteVariables.scss';
        
        @mixin desktopNavbar {
            #navbar {
                .burgerIcon {
                    display: none;
                }
        
                .nav {
                    overflow: hidden;
                    background-color: $navy;
                    vertical-align: middle;
                    height: 70px;
                    line-height: 70px;
                    color: $blizzard;
                    position: fixed;
                    top: 0;
                    width: 100%;
                    display: block;
                    z-index: 99999999;
        
                    .leftBlock, .midBlock, .rightBlock {
                        display: inline-block;
                        vertical-align: middle;
                        height: 70px;
                        padding: 0px;
                        margin: 0px;
                        line-height: 70px;
                    }
        
                    .leftBlock {
                        width: 20%;
        
                        .imgLogo {
                            margin-left: 10px;
                            margin-top: 5px;
                            max-width: 120px;
                        }
                    }
        
                    .midBlock {
                        width: 60%;
                        text-align: center;
        
                        .navbar-nav {
                            display: inline-flex;
                            flex-wrap: nowrap;
                            flex-grow: 2;
                            flex-shrink: 2;
                            list-style: none;
                            vertical-align: middle;
                            margin: 0px;
                            padding: 0px;
        
                            .nav-item {
                                max-width: 175px;
                                color: $white;
                                display: inline-block;
                                vertical-align: middle;
                                height: 70px;
        
                                .btn-link {
                                    font-size: 16px;
                                    text-align: right;
                                    color: $white;
                                    padding: 14px;
                                    line-height: 20px;
                                    text-decoration: none;
                                    vertical-align: middle;
        
                                    span {
                                        font-family: 'Font Awesome Solid';
                                        line-height: 60px;
                                        height: 60px;
                                        vertical-align: middle;
                                        padding: 5px;
                                    }
                                }
        
                                &.dropdown {
                                    font-size: 16px;
                                    text-align: right;
                                    line-height: 20px;
                                    text-decoration: none;
                                    vertical-align: middle;
        
                                    .dropbtn {
                                        font-size: 16px;
                                        text-align: right;
                                        line-height: 20px;
                                        text-decoration: none;
                                        vertical-align: middle;
        
                                        span {
                                            font-family: 'Font Awesome Solid';
                                            line-height: 60px;
                                            height: 60px;
                                            vertical-align: middle;
                                            padding: 5px;
                                        }
                                    }
        
                                    .dropdown-content {
                                        display: none;
                                        position: fixed;
                                        top: 68px;
                                        text-align: center;
                                        background-color: $star-command;
                                        min-width: 160px;
                                        box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
                                        z-index: 99999999999;
        
                                        .dropdown-header {
                                            color: $blizzard;
                                        }
        
                                        .dropdown-item {
                                            color: $powder;
                                            padding: 12px 16px;
                                            text-decoration: none;
                                            display: block;
        
                                            &:hover {
                                                background-color: $blizzard;
                                                color: $navy;
                                            }
                                        }
                                    }
        
                                    &:hover {
                                        background-color: $star-command;
        
                                        .dropdown-content {
                                            display: block;
                                        }
                                    }
                                }
                            }
                        }
                    }
        
                    .rightBlock {
                        width: 20%;
                    }
                }
            }
        }
        

        站点 SCSS 可以简单地是:

        @import '../../FontAwesome/scss/fontawesome.scss';
        @import '../../FontAwesome/scss/regular.scss';
        @import '../../FontAwesome/scss/solid.scss';
        
        @import 'siteVariables.scss';
        @import 'mixins.scss';
        
        //import other stuff here
        
        html, body {
            height: 100%;
            overflow: hidden;
            width: 100%;
            font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
            margin: 0px;
            @include mobileOrDesktop;
        
            .container-fluid {
                overflow: auto;
        
                main {
                    padding: 15px;
                }
            }
        
            #blazor-error-ui {
                background: lightyellow;
                bottom: 0;
                box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
                display: none;
                left: 0;
                padding: 0.6rem 1.25rem 0.7rem 1.25rem;
                position: fixed;
                width: 100%;
                z-index: 1000;
        
                .dismiss {
                    cursor: pointer;
                    position: absolute;
                    right: 0.75rem;
                    top: 0.5rem;
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-21
          • 1970-01-01
          • 1970-01-01
          • 2014-02-14
          • 2012-06-19
          • 1970-01-01
          • 1970-01-01
          • 2013-02-28
          相关资源
          最近更新 更多