Rails中适当的SCSS资产结构

时间:2012-02-04 06:36:50

标签: css ruby-on-rails asset-pipeline sass

所以,我有一个app/assets/stylesheets/目录结构,如下所示:

   |-dialogs
   |-mixins
   |---buttons
   |---gradients
   |---vendor_support
   |---widgets
   |-pages
   |-structure
   |-ui_elements

在每个目录中,有多个sass partials(通常是* .css.scss,但是一个或两个* .css.scss.erb)。

我可能会假设很多,但是rails应该自动编译那些目录中的所有文件,因为application.css中有*= require_tree .,对吧?

我最近尝试通过删除所有颜色变量并将它们放在根app/assets/stylesheets文件夹(_colors.css.scss)中的文件中来重构这些文件。然后我在名为master.css.scss的根app/assets/stylesheets文件夹中创建了一个文件,如下所示:

// Color Palette 
@import "colors";

// Mixins
@import "mixins/buttons/standard_button";
@import "mixins/gradients/table_header_fade";
@import "mixins/vendor_support/rounded_corners";
@import "mixins/vendor_support/rounded_corners_top";
@import "mixins/vendor_support/box_shadow";
@import "mixins/vendor_support/opacity";

我真的不明白rails如何处理资产编译的顺序,但它显然不利于我。看来没有一个文件意识到他们有任何变量或mixins被导入,所以它抛出错误,我无法编译。

Undefined variable: "$dialog_divider_color".
  (in /home/blah/app/assets/stylesheets/dialogs/dialog.css.scss.erb)

Undefined mixin 'rounded_corners'.
  (in /home/blah/app/assets/stylesheets/widgets.css.scss)

变量$dialog_divider_color在_colors.css.scss中明确定义,_master.css.scss导入颜色和我的所有mixin。但显然铁路没有得到那份备忘录。

我是否可以通过某种方式修复这些错误,或者我是否需要将所有变量定义放回每个文件以及所有mixin导入中?

不幸的是,this guy似乎并不认为这是可能的,但我希望他错了。非常感谢任何想法。

6 个答案:

答案 0 :(得分:122)

CSS的问题是,您不希望自动添加所有文件。 浏览器加载和处理工作表的顺序至关重要。所以你总是会明确地导入你所有的CSS。

作为一个例子,假设您有一个normalize.css表,以获得默认外观而不是所有可怕的不同浏览器实现。这应该是浏览器加载的第一个文件。如果您只是在css导入中的某个位置随机包含此工作表,那么它将不仅覆盖浏览器默认样式,还会覆盖在其之前加载的所有css文件中定义的任何样式。对于变量和混合,情况也是如此。

Roy Tomeij看到Euruko2012的演示文稿后,如果你需要管理很多CSS,我决定使用以下方法。

我通常使用这种方法:

  1. 将所有现有.css文件重命名为.scss
  2. 从application.scss
  3. 中删除所有内容

    开始将@import指令添加到application.scss

    如果你使用twitters bootstrap和你自己的一些css表,你必须首先导入bootstrap,因为它有一个表重置样式。 因此,您需要将@import "bootstrap/bootstrap.scss";添加到application.scss

    bootstrap.scss文件如下所示:

    // CSS Reset
    @import "reset.scss";
    
    // Core
    @import "variables.scss";
    @import "mixins.scss";
    
    // Grid system and page structure
    @import "scaffolding.scss";
    
    // Styled patterns and elements
    @import "type.scss";
    @import "forms.scss";
    @import "tables.scss";
    @import "patterns.scss";
    

    您的application.scss文件如下:

    @import "bootstrap/bootstrap.scss";
    

    由于导入的顺序,您现在可以使用在其后导入的任何其他@import "variables.scss";文件中加载.scss的变量。因此,它们可以在引导程序文件夹中的type.scss中使用,也可以在my_model.css.scss中使用。

    在此之后创建名为partialsmodules的文件夹。这将是大多数其他文件的位置。您可以将导入添加到application.scss文件中,使其看起来像:

    @import "bootstrap/bootstrap.scss";
    @import "partials/*";
    

    现在,如果您在主页上制作一篇文章样式。只需创建partials/_article.scss,它就会被添加到已编译的application.css中。由于导入顺序,您还可以在自己的scss文件中使用任何bootstrap mixins和变量。

    到目前为止我发现的这个方法的唯一缺点是,有时你必须强制重新编译部分/ * .scss文件,因为rails不会总是为你做。

答案 1 :(得分:7)

创建以下文件夹结构:

+ assets
|
--+ base
| |
| --+ mixins (with subfolders as noted in your question)
|
--+ styles
  |
  --+ ...

在文件夹base中创建一个文件“globals.css.scss”。在此文件中,声明所有导入:

@import 'base/colors';
@import 'base/mixins/...';
@import 'base/mixins/...';

在application.css.scss中,您应该:

*= require_self
*= depends_on ./base/globals.css.scss
*= require_tree ./styles

作为最后一步(这很重要),在每个要使用变量或mixins的样式文件中声明@import 'base/globals'。您可能会考虑这种开销,但我实际上喜欢您必须在每个文件中声明样式的依赖关系。当然,重要的是你只在globals.css.scss中导入mixins和变量,因为它们不添加样式定义。否则,样式定义将在预编译文件中多次包含...

答案 2 :(得分:7)

要使用变量等跨文件,需要使用@import指令。文件按指定的顺序导入。

然后,使用application.css来要求声明导入的文件。这是实现你想要的控制的方法。

最后,在layout.erb文件中,您可以指定要使用的“master”css文件

示例将更有帮助:

假设您的应用中有两个模块需要不同的css集:“application”和“admin”

文件

|-app/
|-- assets/
|--- stylesheets/
|     // the "master" files that will be called by the layout
|---- application.css
|---- application_admin.css
|
|     // the files that contain styles
|---- config.scss
|---- styles.scss
|---- admin_styles.scss
|
|     // the files that define the imports
|---- app_imports.scss
|---- admin_imports.scss
|
|
|-- views/
|--- layouts/
|---- admin.html.haml
|---- application.html.haml

这里是文件里面的内容:

-------- THE STYLES

-- config.scss
// declare variables and mixins
$font-size: 20px;

--  app_imports.scss
// using imports lets you use variables from `config` in `styles`
@import 'config'
@import 'styles'

-- admin_imports.scss
// for admin module, we import an additional stylesheet
@import 'config'
@import 'styles'
@import 'admin_styles'

-- application.css
// in the master application file, we require the imports
*= require app_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self

-- application_admin.css
// in the master admin file, we require the admin imports
*= require admin_imports
*= require some_other_stylesheet_like_a_plugin
*= require_self


-------- THE LAYOUTS

-- application.html.haml
// in the application layout, we call the master css file
= stylesheet_link_tag "application", media: "all"

--  admin.html.haml
// in the admin layout, we call the admin master css file
= stylesheet_link_tag "application_admin", media: "all"

答案 3 :(得分:3)

根据this question,您可以使用application.css.sass,以便在模板之间定义导入和共享变量。

=>这似乎只是名称问题。

另一种方式可以是include everything and disable this pipeline

答案 4 :(得分:1)

我有一个非常类似的问题。帮助我的是在导入部分时将下划线放入@import语句。所以

@import "_base";

而不是

@import "base";

这可能是一个奇怪的错误......

答案 5 :(得分:0)

我的解决方案是让 application.css.scss 包含所有导入:

@import "./inputs";
@import "./buttons";
@import "./rails";
@import "./base";
@import "./checked-border";
@import "./tailwind-extended";
@import "./helpers";
@import "./custom";
@import "./overrides";

然后添加:

@import "./constants";

到使用常量的文件