Rails资产pipe道解决scheme适用于IE 4096select器/样式表限制

问题

微软的IE支持文档解释说,在Internet Explorer 6-9中:

  1. 没有应用前31个样式标签之后的所有样式标签。
  2. 前4095条规则之后的所有样式规则都不适用。
  3. 在使用@import规则连续导入导入其他样式表的外部样式表的页面上,会忽略深度超过三级的样式表。

脚本演示有很多这个问题的证据。 另见保佑 。

需要解决scheme

我们需要一种方法来分割由资产pipe道中的Sprockets生成的编译样式表,以保持最大select器数量低于4096,并在部署的Rails应用程序的HTML中链接到它们。 我们怎样才能把经过处理的资产(特别是样式表)的编译输出作为parameter passing给一个方法,然后才能修改这些文件呢?

看到下面的尝试开始的地方。 如果有人能够帮助我find一种方法来实现(或者全新的解决scheme),那太棒了!

现有的解决scheme尝试

  • 祝福是为了解决这个问题而创build的,通过分割样式表来保持每张表的最大select器数在极限以下。 祝福在node.js服务器上运行 我还没有看到一个Ruby的等价物呢。 埃里克·菲尔兹(Eric Fields)试图将用罗盘编译的资产提供给Bless (在节点中运行),但该解决scheme依赖于Compass处理资产编译,因此似乎不适用于资产pipe道。 请注意,不是链接到多个样式表,Bless向第一个表添加了@include语句,这可能是避免触及标记的方法。

  • 当Christian Peters(@crispy) 发现这个问题时 ,他实现了一个像Bless一样的分割器 ,它也将Compass的输出传递给了一个自定义模块,在Rails 3.1之前,这个模块运行良好。 后来,他用SprocketsEngine改编了他的分离器,以便与Rails Assetpipe道集成 。 我尝试过实现新的代码,但它似乎并没有自动工作(虽然分配器工作正常,当在控制台手动调用)。

相关信息

有关IE 6-9中CSS限制的更多信息,请参阅以下相关问题:

  • IE 8对每页样式表的数量是否有限制?
  • Internet Explorer的CSS规则限制

我们有一个自动的(尽pipe在某种程度上是尴尬的)解决scheme,适用于Rails 3.1应用程序的生产环境,并具有资产pipe道。 瑞安在他的问题中已经提到了解决scheme,但我试图提出一个更全面的答案。

资产pipe道通过不同的Sprocket引擎pipe理资产。

所以你可能有例如一个ie.css.sass.erb通过ERB Sprocket引擎运行,然后传递给Sass Sprocket引擎等,但它总是一个文件和一个文件。

在这个特殊的问题中,我们想要有1个入站文件和n个出站文件。 我们还没有find一种方法来使这个链轮成为可能。 但是我们发现了一个解决方法:

提供一个包含完整样式表的ie_portion2.css.sass.split2和一个只导入完整ie.css文件的ie_portion2.css.sass.split2

 //= include 'ie.css' 

对于split2文件扩展名,我们注册一个Sprockets Engine:

 require 'css_splitter' Rails.application.assets.register_engine '.split2', CssSplitter::SprocketsEngine 

使用split2扩展评估资产时,我们将其内容传递给CssSplitter并指示它提取第2部分(> 4095select器):

 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 

这也适用于更多的部分(split3,…)。

CSS Splitter识别有效的地方,样式表可以被拆分成less于4096个select器的部分,并返回所需的部分。

结果是一个ie_portion2.css,你必须在head和precompile分开链接。

我希望我的修订版CSS Splitter Gist足够完整,可以使用这个解决scheme。

更新:

上面提到的CssSplitter已经被释放为一个gem: https : //github.com/zweilove/css_splitter

我在生产中使用的解决scheme非常简单,不是自动化的,但工作得很好。 对我来说,这是显而易见的事情,所以也许你已经想过了,不喜欢它 – 无论哪种方式,我们走吧:

我假设你正在使用sass,如果没有,我想你应该:)

首先 ,将你的application.css.scss拆分为单独的文件,例如: application_a.css.scssapplication_b.css.scss

其次 ,在你的application.css.scss文件中,使用:

 @import "application_a" @import "application_b" 

第三 ,在您的布局模板中,包含完整的文件或两个部分:

 <!--[if !IE]><!--> # link to application.css.scss <!--<![endif]--> <!--[if IE]> # link to application_a.css.scss # link to application_b.css.scss <![endif]--> 

注意:不要通过资产pipe道生成你的样式表清单文件,通过sass和@import语句来执行,其他的一切都会导致问题。