用于IE 4096选择器/样式表限制的Rails资产管道解决方案

时间:2012-08-25 22:23:47

标签: css ruby-on-rails internet-explorer asset-pipeline sprockets

问题

Microsoft's IE support documentation在Internet Explorer 6-9中解释:

  
      
  1. 未应用前31个样式标记之后的所有样式标记。
  2.   
  3. 不应用前4,095条规则之后的所有样式规则。
  4.   
  5. 在使用@import规则连续导入导入其他样式表的外部样式表的页面上,将忽略深度超过三级的样式表。
  6.   

script demos有很多证据表明存在这个问题。另请参阅Bless

需要解决方案

我们需要一种方法来分割资产管道中由Sprockets生成的已编译样式表,以使最大选择器数量保持在4096以下,并在部署的Rails应用程序的HTML中链接到它们。 我们如何将已处理资产(特别是样式表)的编译输出作为参数传递给可以修改文件的方法?

请参阅以下尝试开始的地方。如果有人可以帮我找到一种方法来制作可操作的(或者是一种全新的解决方案),那就太棒了!

现有解决方案尝试

    创建
  • Bless是为了通过拆分样式表来解决此问题,以使每张纸的最大选择器数量保持在限制之下。 Bless在node.js的服务器上运行。我还没有看到类似Ruby的东西。 Eric Fields尝试serve assets compiled with compass to Bless(在节点中运行),但该解决方案依赖于Compass处理资产编译,因此似乎不适用于资产管道。 请注意,Bless不是链接到多个样式表,而是将@include语句添加到第一张表中,这可能是为了避免触及标记。

  • 当Christian Peters(@crispy)discovered this problem时,他implemented a splitter喜欢Bless,它也将Compass输出传递给自定义模块,该模块在Rails 3.1之前运行良好。后来他adapted his splitter with a SprocketsEngine for integration with the Rails Asset pipeline。我已尝试实现新代码,但它似乎没有自动运行(虽然在控制台中手动调用时分割器工作正常)。

相关信息

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

2 个答案:

答案 0 :(得分:10)

我们有一个自动化(虽然有些尴尬)解决方案,正在为生产Rails 3.1应用程序而设置资产管道。 Ryan已在他的问题中引用了解决方案,但我尝试提出更全面的答案。

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

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

在这个特殊问题中,我们希望有1个入站文件和n个出站文件。 我们还没有找到一种方法来实现链轮的可能性。但我们找到了一个解决方法:

提供包含完整样式表的ie.css.sass和只导入完整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部分(> 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

这也适用于其他部分(split3,...)。

The CSS Splitter识别可以将样式表拆分为少于4096个选择器的部分的有效位置,并返回所请求的部分。

结果是一个ie_portion2.css,您必须在头部和预编译中单独链接。

我希望我修订后的CSS Splitter Gist足以使用解决方案。

<强>更新

上面的CssSplitter提及现已发布为宝石:https://github.com/zweilove/css_splitter

答案 1 :(得分:7)

我在制作中使用的解决方案非常简单,不是自动化的,但效果非常好。 对我来说这是显而易见的事情,所以也许你已经考虑过它并且不喜欢它 - 不管怎样,我们走了:

我假设你正在使用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]-->

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