Rya*_*lah 34 css internet-explorer ruby-on-rails sprockets asset-pipeline
Microsoft的IE支持文档在Internet Explorer 6-9中解释了这一点:
- 不应用前31个样式标记之后的所有样式标记.
- 不应用前4,095条规则之后的所有样式规则.
- 在使用@import规则连续导入导入其他样式表的外部样式表的页面上,将忽略深度超过三级的样式表.
我们需要一种方法来分割由资源管道中的Sprockets生成的已编译样式表,以使最大选择器数保持在4096以下,并在部署的Rails应用程序的HTML中链接到它们.我们如何将已处理资产(特别是样式表)的编译输出作为参数传递给可以修改文件的方法?
请参阅以下尝试开始的地方.如果有人可以帮我找到一种方法来制作可操作的(或者一种全新的解决方案),那就太棒了!
创建Bless是为了解决这个问题,方法是拆分样式表以使每张纸的最大选择器数量保持在限制之下.Bless在node.js的服务器上运行.我还没有看到类似Ruby的东西.Eric Fields试图将用罗盘编译的资产提供给Bless(在节点中运行),但该解决方案依赖于Compass处理资产编译,因此似乎不适用于资产管道.请注意,Bless不是链接到多个样式表,而是将@include语句添加到第一个工作表,这可能是要避免触及标记的方法.
当Christian Peters(@crispy)发现这个问题时,他实现了像Bless这样的分离器,它也将Compass输出传递给自定义模块,该模块在Rails 3.1之前运行良好.后来,他使用SprocketsEngine调整了他的拆分器,以便与Rails Asset管道集成.我已经尝试实现新代码,但它似乎没有自动运行(虽然在控制台中手动调用时分割器工作正常).
有关IE 6-9中CSS限制的更多信息,请参阅以下相关问题:
cri*_*spy 10
我们有一个自动化(虽然有点尴尬)的解决方案,在生产中为Rails 3.1应用程序提供资产管道.Ryan已经在他的问题中提到了解决方案,但我试图提出一个更全面的答案.
资产管道通过不同的Sprocket引擎管道资产.
所以你可能有一个例如一个ie.css.sass.erb贯穿ERB Sprocket引擎,然后传递给Sass Sprocket引擎等.但它始终是一个文件和一个文件输出.
在这个特殊问题中,我们希望有1个入站文件和n个出站文件.我们还没有找到一种方法来实现链轮的可能性.但是我们找到了一个解决方法:
提供一个ie.css.sass包含完整样式表和一个ie_portion2.css.sass.split2只导入完整的ie.css文件的样式:
//= include 'ie.css'
Run Code Online (Sandbox Code Playgroud)
对于split2文件扩展名,我们注册了Sprockets Engine:
require 'css_splitter'
Rails.application.assets.register_engine '.split2', CssSplitter::SprocketsEngine
Run Code Online (Sandbox Code Playgroud)
在使用split2扩展评估资产时,我们将其内容传递给CssSplitter并指示它提取第2部分(> 4095个选择器):
require 'tilt'
module CssSplitter
class SprocketsEngine < Tilt::Template
def self.engine_initialized?
true
end
def prepare
end
def evaluate(scope, locals, &block)
part = scope.pathname.extname =~ /(\d+)$/ && $1 || 0
CssSplitter.split_string data, part.to_i
end
end
end
Run Code Online (Sandbox Code Playgroud)
这也适用于其他部分(split3,...).
CSS Splitter识别可以将样式表拆分为少于4096个选择器的部件并返回所请求部件的有效位置.
结果是一个ie_portion2.css,您必须分别在头部和预编译中进行链接.
我希望我修改过的CSS Splitter Gist足以使用该解决方案.
更新:
上面提到的CssSplitter现已发布为宝石:https://github.com/zweilove/css_splitter
我在生产中使用的解决方案非常简单,不是自动化的,但效果非常好.对我来说这是显而易见的事情,所以也许你已经考虑过它并且不喜欢它 - 不管怎样,我们走了:
我假设你正在使用sass,如果没有,我认为你应该:)
首先,拆分application.css.scss单独的文件,例如:
application_a.css.scss和application_b.css.scss
其次,在您的application.css.scss文件中,使用:
@import "application_a"
@import "application_b"
Run Code Online (Sandbox Code Playgroud)
第三,在布局模板中,包括完整文件或两个部分:
<!--[if !IE]><!-->
# link to application.css.scss
<!--<![endif]-->
<!--[if IE]>
# link to application_a.css.scss
# link to application_b.css.scss
<![endif]-->
Run Code Online (Sandbox Code Playgroud)
附注:不要通过资产管道产生样式表清单文件,通过SASS做到这一点,它的@import声明,其他的一切都会导致问题.