使用 Rails 3.1 资产管道有条件地使用某些 css
Posted
技术标签:
【中文标题】使用 Rails 3.1 资产管道有条件地使用某些 css【英文标题】:Using Rails 3.1 assets pipeline to conditionally use certain css 【发布时间】:2011-10-31 07:59:41 【问题描述】:我正在使用 Rails 3.1.rc5 构建我的第一个单独的 Rails 应用程序。我的问题是我想让我的网站有条件地呈现各种 CSS 文件。我正在使用 Blueprint CSS,并且我试图让 sprockets/rails 在大多数情况下呈现 screen.css
,print.css
仅在打印时呈现,ie.css
仅在从 Internet Explorer 访问网站时呈现。
不幸的是,application.css
清单中的默认 *= require_tree
命令包含 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"
这可行,但不是特别漂亮。我已经进行了几个小时的搜索,甚至可以做到这一点,但我希望有一些我刚刚错过的更简单的方法来做到这一点。如果我什至可以有选择地呈现某些目录(不包括子目录),那么整个过程就会变得不那么僵硬。
谢谢!
【问题讨论】:
【参考方案1】:今天遇到了这个问题。
最终将所有 IE 特定样式表放入 lib/assets/stylesheets 并为每个 IE 版本创建一个清单文件。然后在 application.rb 中将它们添加到要预编译的内容列表中:
config.assets.precompile += ["ie9.css", "ie7.css", "ie8.css", "ie.css"]
在您的布局中,有条件地包含这些清单文件,您就可以开始了!
【讨论】:
【参考方案2】:我发现了一种方法,通过仍然使用资产管道但将样式表分组,从而使其不那么僵化和面向未来。它并不比您的解决方案简单多少,但是此解决方案允许您自动添加新样式表,而无需再次重新编辑整个结构。
您想要做的是使用单独的清单文件来分解。首先你必须重新组织你的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 所指出的,如果您遵循此结构,则必须注意图像引用。你有几个选择:
-
移动图片以遵循相同的模式
请注意,这仅在图像未全部共享时才有效
我认为这对大多数人来说是不可能的,因为它使事情变得过于复杂
限定图片路径:
background: url('/assets/image.png');
使用 SASS 助手:
background: image-url('image.png');
【讨论】:
虽然这是一个很好的文件组织,但我相信它仍然以与问题本身相同的方式解决了基本问题。 @semperos,您说得对,解决方案的形状基本相同,但我的建议仍然允许我们将资产管道用于整个样式表。我不确定是否有另一种方法可以选择性地包含部分样式,除非它位于单独的样式表中。至少这种方式我们只编译成少数 CSS 文件。 Rails Asset Pipeline 指南中的类似内容实际上会很好。谢谢 有一个问题:如果你遵循这个结构并使用简单的.css
文件,那么你所有的图像都会被破坏。例如。 background: url('image.png')
将被转换为路径 /assets/all/image.png
(注意路径中的 all)。相反,这有效:background: url('/assets/image.png)
。如果有更简单的解决方案,请发布。除了使用具有可能正确解析路径的辅助方法的 SASS 之外。
@ExiRe,是的。任何不遵循标准模式的样式表或 JS 文件/清单都需要添加到预编译数组中(参见:guides.rubyonrails.org/asset_pipeline.html#precompiling-assets)【参考方案3】:
这是一个非常巧妙的方法。我在 html 或 modernizr 上使用条件类。请参阅这篇文章,了解什么是做什么的。 modernizr-vs-conditional-classes-on-html
【讨论】:
以上是关于使用 Rails 3.1 资产管道有条件地使用某些 css的主要内容,如果未能解决你的问题,请参考以下文章
>=Rails 3.1 如何在资产管道中包含 IE 特定的 YAML-CSS 文件
Rails 3.1 资产管道和手动订购的 Javascript 需要