CSS Rails 中正确的 SCSS 资产结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9138946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:49:08  来源:igfitidea点击:

Proper SCSS Asset Structure in Rails

cssruby-on-railsasset-pipelinesass

提问by David Savage

So, I have an app/assets/stylesheets/directory structure that looks something like this:

所以,我有一个app/assets/stylesheets/看起来像这样的目录结构:

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

In each directory, there are multiple sass partials (usually *.css.scss, but one or two *.css.scss.erb).

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

I might be assuming a lot, but rails SHOULD automatically compile all the files in those directories because of *= require_tree .in application.css, right?

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

I recently have tried restructuring these files by removing all color variables and placing them in a file in the root app/assets/stylesheetsfolder (_colors.css.scss). I then created a file in the root app/assets/stylesheetsfolder called master.css.scss which looks like this:

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

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

I don't really understand how rails handles the order of asset compilation, but it's obviously not in my favor. It appears none of the files realize they have any variables or mixins being imported, and so it throws errors and I can't compile.

我真的不明白 rails 如何处理资产编译的顺序,但这显然对我不利。似乎没有文件意识到它们导入了任何变量或mixin,因此它会引发错误并且我无法编译。

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)

The variable $dialog_divider_coloris clearly defined in _colors.css.scss, and _master.css.scssis importing colors and all my mixins. But apparently rails didn't get that memo.

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

Is there some way I can fix these errors, or will I need to resort to putting all my variable definitions back into each individual file, as well as all the mixin imports?

有什么方法可以解决这些错误,还是需要将所有变量定义放回每个单独的文件以及所有 mixin 导入?

Unfortunately, this guydoesn't seem to think it's possible, but I'm hoping he's wrong. Any thoughts are greatly appreciated.

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

回答by Benjamin Udink ten Cate

The problem with CSS is, you do not want to automatically add all files. The order of which your sheets are loaded and processed by the browser is essential. So you will always end up explicitly importing all your css.

CSS 的问题是,您不想自动添加所有文件。浏览器加载和处理工作表的顺序至关重要。因此,您最终总是会明确导入所有 css。

As an example, lets say you have a normalize.csssheet, to get a default look instead of all the horrible different browser implementations. This should be the first file the browser loads. If you just randomly include this sheet somewhere in your css imports, it will then not only override the browser default styles, but also any styles defined in all css files that were loaded before it. This goes the same for variables and mixins.

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

After seeing a presentation by Roy Tomeijat Euruko2012 I decided for the following approach if you have a lot of CSS to manage.

Euruko2012上看到Roy Tomeij的演讲后,如果您有很多 CSS 需要管理,我决定采用以下方法。

I generally use this approach:

我一般使用这种方法:

  1. Rename all existing .css files to .scss
  2. Remove all contents from application.scss
  1. 将所有现有的 .css 文件重命名为 .scss
  2. 从 application.scss 中删除所有内容

Start adding @import directives to application.scss.

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

If you are using twitters bootstrap and a few css sheets of your own, you have to import bootstrap first, because it has a sheet to reset styles. So you add @import "bootstrap/bootstrap.scss";to your application.scss.

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

The bootstrap.scss file looks like:

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

And your application.scssfile look like:

你的application.scss文件看起来像:

@import "bootstrap/bootstrap.scss";

Because of the order of the imports, you can now use the variables, loaded with @import "variables.scss";in any other .scssfile imported after it. So they can be used in type.scssin the bootstrap folder but also in my_model.css.scss.

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

After this create a folder named partialsor modules. This will be the place of most of the other files. You can just add the import to the application.scssfile so it will look like:

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

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

Now if you make a bit of css to style an article on your homepage. Just create partials/_article.scssand it will be added to the compiled application.css. Because of the import order you can also use any bootstrap mixins and variables in your own scss files.

现在,如果您使用一些 css 来设计主页上的文章样式。只需创建partials/_article.scss,它将被添加到编译的application.css. 由于导入顺序,您还可以在您自己的 scss 文件中使用任何引导混合和变量。

The only drawback of this method I found so far is, sometimes you have to force a recompile of the partial/*.scss files because rails wont always do it for you.

到目前为止,我发现这种方法的唯一缺点是,有时您必须强制重新编译 partial/*.scss 文件,因为 rails 不会总是为您执行此操作。

回答by emrass

Create the following folder structure:

创建以下文件夹结构:

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

In folder basecreate a file "globals.css.scss". In this file, declare all your imports:

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

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

In you application.css.scss, you should then have:

在你的 application.css.scss 中,你应该有:

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

And as the last step (this is important), declare @import 'base/globals'in every style file where you want to use variables or mixins. You might consider this overhead, but I actually like the idea that you have to declare the dependencies of your styles in every file. Of course, it is important that you only import mixins and variables in the globals.css.scss as they do not add style definitions. Otherwise the style definitions would be included multiple times in your precompiled file ...

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

回答by Doug Lee

to use variables and such across files, you need to use the @import directive. files are imported in order specified.

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

then, use application.css to require the file that declares the imports. this is the way to achieve the control you want.

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

finally, in your layout.erb file, you can specify which "master" css file to use

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

example will be more helpful:

示例会更有帮助:

let's say you have two modules in your app that need different sets of css: "application" and "admin"

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

the files

文件

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

here's what the files look like inside:

这是里面的文件的样子:

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

回答by Coren

According to this question, you can ONLYuse application.css.sassin order to define import and share variables between your templates.

根据这个问题,您只能使用application.css.sass来定义模板之间的导入和共享变量。

=> It seems to be only a matter of name.

=> 这似乎只是名字的问题。

An other way can be to include everything and disable this pipeline.

另一种方法是包含所有内容并禁用此管道

回答by Bernát

I had a very similar problem. What helped me was to put in the underscore to the @import statement when importing the partial. So

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

@import "_base";

instead of

代替

@import "base";

It might be a strange bug...

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