页面特定Sass文件和复制

时间:2012-10-19 11:40:58

标签: css ruby-on-rails ruby-on-rails-3 sass sprockets

我真的很难在Rails 3.1项目中构建Sass文件,以避免大量重复...

我有以下结构,application.css.scss作为主要布局的一部分导入:

application.css.scss
  - [*= require] main.css.scss
      - [@import] 'variables';
      - [@import]'bootstrap_overrides';
      - [@import]'bootstrap';
      - [@import]'base_elements';
      - [@import]'superstructure';
      - [@import]'modules';

到目前为止一切顺利。所有这些文件都由链轮组合成一个文档。但是,我想进一步模块化我的Sass,特定于页面的文件或文件在我的网站的各个区域共享。

所以在我的GalleryResource#show页面上我需要使用额外的Sass文件:

resource.scss
gallery_resource.scss
badges.scss

也许是来自lib的css文件:

gallery_lib.scss

这些文件需要引用已在application.css中导入的许多文件。他们需要使用variables.css.scss中定义的变量和bootstrap中定义的mixins。所以我被迫在每个使用它们的文件中重新导入这些文件,导致大量重复。我可以为每个页面编写一个清单文件,但这是一个维护噩梦,仍然会导致重复和两个css文件; application.css和page_specific.css。

那么解决方案是什么?我是否需要使用application.css并将其导入移动到每个特定于页面的文件中?因此,使用上面的示例,我最终会得到一个如下所示的清单文件:

gallery_resource_manifest.css.scss
      - [*= require] gallery_lib.css
      - [*= require] gallery_resource.css.scss
         - [@import] 'variables';
         - [@import]'bootstrap_overrides';
         - [@import]'bootstrap';
         - [@import]'base_elements';
         - [@import]'superstructure';
         - [@import]'modules';
         - [@import]'resource';
         - [@import]'gallery_resource';
         - [@import]'gallery';
         - [@import]'badges';

2 个答案:

答案 0 :(得分:9)

我还试图在组织样式时做同样的事情。 Rails通过不断为您生成基于控制器的样式表,几乎将您推向了这个方向。最后,我选择将所有内容添加到application.sass。此方法的主要优点是您只在页面加载时发出一个请求,并且最终不必重新导入用户在最后一页上请求的代码。

我的个人意见是,如果你很好地抽象你的CSS,你只需要使用一个样式表,因为你没有很多特定于视图的代码,而是首先将它们带入样式表。无论哪种方式,替代方案(根据页面需要随机加载模块,而您可能在上一页上完成相同操作)听起来并不像是在解决这个问题。此外,您正在对全新文件提出更多请求。

组织CSS可能有点棘手。以下是我通常如何组织样式以及样式表目录的示例。此方法适用于单个命名空间(应用程序),或者如果需要,可以分解为多个命名空间(即管理员,应用程序)。

application.sass

// vendor ----------------------------------------------------------------------

// compass

@import "compass/reset"
@import "compass/css3/box-shadow"
@import "compass/css3/border-radius"
@import "compass/css3/box-sizing"
@import "compass/css3/opacity"
@import "compass/layout/sticky-footer"
@import "compass/utilities"

// grid

@import "susy"



// application -----------------------------------------------------------------


// base

// for mixins, variables and helpers to aid in building
// the application. no styling of actual elements should
// go in base.

@import "base/colors"
@import "base/fonts"
@import "base/mixins"
@import "base/grid"


// layout

// generic site styles. this includes site chrome styles
// such as the header, footer, flash messages, nav, as well
// as common patterns used around the site like forms, type,
// links, etc. the loose idea is that you could take these
// styles and create a similar "layout" but it wouldn't
// include contextual patterns like books, originals, etc.

@import "layout/buttons"
@import "layout/content"
@import "layout/header"
@import "layout/flash"
@import "layout/forms"
@import "layout/footer"
@import "layout/links"
@import "layout/tooltips"
@import "layout/typography"


// modules

// elements used on multiple pages that are loosely tied
// to our domain and data structure. examples are dependent
// on the needs of your site. as a general guideline, all 
// modules should be used on multiple pages. elements used 
// on a single page should be included in views.

@import "modules/articles"
@import "modules/buttons"
@import "modules/forms"
@import "modules/links"
@import "modules/pagination"
@import "modules/users"
@import "modules/stats"
@import "modules/some_other_domain_specific_styling_unique_to_your_site"


// views

// elements used on a single page. these styles are
// often needed to help put finishing touches on a
// page where modules didn't quite line up perfectly,
// or where a page has completely unique elements.
// these styles could often be abstracted to modules
// but lack a reason to do so. keeping them here helps
// explain their singular usage.

@import "views/welcome/index"
@import "views/settings/all"
@import "views/articles/show"
@import "views/users/show"

以这种方式组织您的样式有助于为每个文件创建一个单一的责任(看起来您也尝试这样做)。我发现这使得CSS更易于维护。此外,如果您需要添加媒体查询或使用给定模块定位特定浏览器,它会为您提供一个与上下文相关的位置,同时仍然保持您的代码清晰且分离。

注意,如果您只有一个名称空间,则会使用上面的示例。如果您有一个管理部分(或其他),您可以将所有这些目录/文件放在“应用程序”目录中,并为“admin”创建类似的结构。这将在app/stylesheets中留下以下结构。

- admin
- application
- admin.sass
- application.sass

您甚至可以创建一个结构来共享两者之间的项目,但这可能是必要的,也可能不是必需的。关键是你有很多灵活性和组织能力,无论你需要做什么。如果你这么倾向,这个结构也可以用于JS。这避免了重新加载模块和发出新请求的问题。

FWIW,我试图找到一个解决方案,只引入我需要的每页(你的问题),但最后我只是在整体上传递了更多的位,同时增加了我的请求数量。 YMMV。

希望这有助于您前进!

答案 1 :(得分:3)

我通过从rspec获取一个提示并创建一个_sass_helper.sass部分来解决这个问题,该部分包含我所有的非直接式导入(变量,mixins,占位符),然后将其包含在每个部分的顶部。文件。非代码位很重要,因为如果_sass_helper.sass包含任何样式,它们将被写入每个文件。

这有效地允许我为每个文件获得相同的“Sass环境”,而不需要任何代码重复。

我的树有这样的组织:

includes/
  _variables.sass
  _mixins.sass
  _extends.sass
posts/
  _post_partial_1.sass
  _post_partial_2.sass
application.sass
posts.sass
_sass_helper.sass

然后,像posts.sass这样的东西看起来像:

@import 'sass_helper'
@import 'posts/post_partial_1'
@import 'posts/post_partial_2'

.some.globally.shared.post
  styles: here

效果很好。 post partials不需要sass帮助器,所以我最终每个控制器有一个主文件,各个功能部分,各地都有相同的环境。