Microsoft's IE support documentation在Internet Explorer 6-9中解释:
- 未应用前31个样式标记之后的所有样式标记。
- 不应用前4,095条规则之后的所有样式规则。
- 在使用@import规则连续导入导入其他样式表的外部样式表的页面上,将忽略深度超过三级的样式表。
醇>
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限制的更多信息,请参阅以下相关问题:
答案 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.scss
和application_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
语句执行,其他一切都会导致问题。