css - IE 4096 选择器/样式表限制的 Rails Assets 管道解决方案

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

问题

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

  1. All style tags after the first 31 style tags are not applied.
  2. All style rules after the first 4,095 rules are not applied.
  3. On pages that uses the @import rule to continously import external style sheets that import other style sheets, style sheets that are more than three levels deep are ignored.

有很多证据表明 script demos 存在这个问题.另见 Bless .

需要解决方案

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

请参阅以下尝试作为起点。如果有人可以帮助我找到一种方法来实现其中之一的可操作性(或全新的解决方案),那就太棒了!

现有解决方案尝试

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

  • 当克里斯蒂安·彼得斯 (@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 限制的更多信息,请参阅以下相关问题:

最佳答案

我们有一个自动化(尽管有点笨拙)的解决方案,在生产环境中为 Rails 3.1 应用程序工作,并配备了 Assets 管道。 Ryan 已经在他的问题中提到了解决方案,但我试图提出一个更全面的答案。

Assets 管道通过不同的 Sprocket 引擎传输 Assets 。

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

在这个特殊问题中,我们希望有 1 个入站文件和 n 个出站文件。 我们还没有找到用 sprockets 实现这一点的方法。但我们找到了解决方法:

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

//= include 'ie.css'

对于split2文件扩展,我们注册了一个 sprockets 引擎:

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

在使用 split2 扩展评估 Assets 时,我们将其内容传递给 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 现在已经作为 gem 发布:https://github.com/zweilove/css_splitter

关于css - IE 4096 选择器/样式表限制的 Rails Assets 管道解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12126118/

相关文章:

html - 仅在 Win7 上的 IE10/11 上隐藏了某些 HTML,适用于所有其他 IE 版本

html - 如何使 2 个不同的链接具有 2 个不同的 CSS 属性?

ruby-on-rails - ruby/rails 中的日期范围查询

javascript - 如何使用 react-rails gem 预渲染命名空间的 React 组件?

ruby-on-rails - 将实例变量传递给延迟作业

c# - .NET WebBrowser 控件是否可以使用 IE9?

php - Jquery:单独控制重复的类(或div)

css - Div 不会进入包装器?

html - ie8 if-ie block 不起作用

internet-explorer - Css 在 IE 兼容性 View 中不工作