使用Rails 3.1资产管道有条件地使用某些CSS


166

我正在使用Rails 3.1.rc5构建我的第一个单独的Rails应用程序。我的问题是我想让我的网站有条件地呈现各种CSS文件。我正在使用Blueprint CSS,并且试图在screen.css大多数情况下渲染链轮/轨道,print.css仅在打印ie.css时以及从Internet Explorer访问该网站时。

不幸的是,清单中的默认*= require_tree命令application.css包括assets/stylesheets目录中的所有内容,并导致令人不愉快的CSS混乱。我当前的解决方法是一种蛮力方法,其中我分别指定了所有内容:

在application.css中:

*= require_self
*= require home.css
...
*= require blueprint/screen.css

在我的样式表中,部分(haml):

<!--[if lt IE 9]
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
![endif]-->
= stylesheet_link_tag "application"
= stylesheet_link_tag 'blueprint/print', media: 'print'
<!--[if lt IE8]]
= stylesheet_link_tag 'blueprint/ie'
![endif]-->
= javascript_include_tag "application"

这有效,但不是特别漂亮。我已经花了几个小时进行搜索,才能达到目标,但是我希望有一种更简单的方法,而我只是错过了。如果我什至可以选择性地呈现某些目录(不包括子目录),那么整个过程将变得不那么严格。

谢谢!

Answers:


223

我发现了一种方法,可以通过仍然使用资产管道但将样式表进行分组来降低其僵化程度和对未来的要求。它并没有比您的解决方案简单得多,但是该解决方案使您可以自动添加新的样式表,而不必再次重新编辑整个结构。

您要做的是使用单独的清单文件来分解内容。首先,您必须重新组织您的app/assets/stylesheets文件夹:

app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

然后,编辑三个清单文件:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */

接下来,您将更新应用程序布局文件:

<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

最后,不要忘记在您的config / environments / production.rb文件中包含这些新的清单文件:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

更新:

正如Max所指出的那样,如果您遵循这种结构,则必须注意图像参考。您有几种选择:

  1. 移动图像以遵循相同的模式
    • 请注意,这仅在图像未全部共享的情况下有效
    • 我希望这对于大多数人来说都是一个入门者,因为它会使事情变得过于复杂
  2. 限定图像路径:
    • background: url('/assets/image.png');
  3. 使用SASS助手:
    • background: image-url('image.png');

1
尽管这是一个很好的文件组织,但我相信它仍然可以以问题本身的方式解决基本问题。
semperos 2011年

@semperos,您是正确的,解决方案的形状基本相同,但我的建议仍然允许我们将资产管道用于整个样式表。我不确定是否有另一种方法可以选择性地包括部分样式,除非它在单独的样式表中。至少通过这种方式,我们仅编译为少数CSS文件。
gcastro

5
实际上,Rails Asset Pipeline指南中的类似内容会很好。谢谢
Bashar Abdullah '04

3
但是有一个陷阱:如果您遵循这种结构并使用简单的.css文件,那么所有图像将被破坏。例如,background: url('image.png')将转换为路径/assets/all/image.png(注意路径中的所有内容)。相反,这个作品:background: url('/assets/image.png)。如果对此有更简单的解决方案,请发布。除了使用具有帮助程序方法的SASS之外,这些方法可能会正确解析路径。
马克斯

1
@ExiRe,是的。任何不遵循标准模式的样式表或JS文件/清单都需要添加到预编译数组中(请参阅:guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
gcastro 2012年

10

今天遇到了这个问题。

最终将所有IE特定的样式表放入lib / assets / stylesheets,并为每个IE版本创建一个清单文件。然后在application.rb中将它们添加到要预编译的事物列表中:

config.assets.precompile += ["ie9.css", "ie7.css", "ie8.css", "ie.css"]

并且在您的布局中,有条件地包括这些清单文件,您就该走了!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.