34

問題

MicrosoftのIEサポートドキュメントでは、InternetExplorer6-9で次のように説明されています。

  1. 最初の31個のスタイルタグ以降のすべてのスタイルタグは適用されません。
  2. 最初の4,095ルール以降のすべてのスタイルルールは適用されません。
  3. @importルールを使用して、他のスタイルシートをインポートする外部スタイルシートを継続的にインポートするページでは、3レベルを超える深さのスタイルシートは無視されます。

スクリプトデモには、この問題の証拠がたくさんあります。Blessも参照してください。

必要な解決策

アセットパイプラインでSprocketsによって生成されたコンパイル済みスタイルシートを分割して、セレクターの最大数を4096未満に保ち、デプロイされたRailsアプリケーションのHTMLでそれらにリンクする方法が必要です。処理されたアセット(具体的にはスタイルシート)のコンパイル済み出力を、ファイルを変更できるメソッドへの引数として渡すにはどうすればよいですか?

開始する場所については、以下の試みを参照してください。誰かが私がどちらかを運用可能にする方法(またはまったく新しいソリューション)を見つけるのを手伝ってくれるなら、それは素晴らしいことです!

既存のソリューションの試み

  • Blessは、スタイルシートを分割してシートあたりの最大セレクター数を制限内に抑えることにより、この問題を解決するために作成されました。Blessはnode.jsのサーバーで実行されます。Rubyに相当するものはまだ見ていません。Eric Fieldsは、コンパスでコンパイルされたアセットをBless(ノードで実行)に提供しようとしましたが、そのソリューションは、アセットのコンパイルを処理するコンパスに依存しているため、アセットパイプラインでは機能しないようです。複数のスタイルシートにリンクする代わりに、Blessは@include最初のシートにステートメントを追加することに注意してください。これは、マークアップに触れないようにするための方法である可能性があります。

  • Christian Peters(@crispy)がこの問題を発見したとき、彼はBlessのようなスプリッターを実装しました。これは、コンパス出力をカスタムモジュールに渡し、Rails3.1より前はうまく機能していました。その後、Rails Assetパイプラインと統合するために、スプリッターをSprocketsEngineに適合させました。新しいコードを実装しようとしましたが、自動的に機能しないようです(ただし、コンソールで手動で呼び出すとスプリッターは正常に機能します)。

関連情報

IE 6-9のCSS制限の詳細については、次の関連する質問を参照してください。

4

2 に答える 2

10

アセットパイプラインが配置されたRails3.1アプリの本番環境で機能する、自動化された(多少厄介ではありますが)ソリューションがあります。ライアンはすでに彼の質問で解決策を参照しましたが、私はより包括的な答えを考え出すようにしています。

アセットパイプラインは、さまざまなスプロケットエンジンを介してアセットをパイプします。

たとえばie.css.sass.erb、ERB Sprocketエンジンを介して実行され、Sass Sprocketエンジンなどに渡される場合があります。ただし、これは常に1つのファイルインと1つのファイルアウトです。

この特別な問題では、1つのインバウンドファイルとnのアウトバウンドファイルが必要です。スプロケットでこれを可能にする方法は見つかりませんでした。しかし、回避策が見つかりました。

ie.css.sass完全なスタイルシートを含むを提供しie_portion2.css.sass.split2、完全なie.cssファイルをインポートするだけのを提供します。

//= include 'ie.css'

ファイル拡張子についてはsplit2、SprocketsEngineを登録します。

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、...)でも機能します。

CSSスプリッターは、スタイルシートを4096未満のセレクターでパーツに分割できる有効な場所を認識し、要求されたパーツを返します。

結果はie_portion2.cssであり、これをヘッドにリンクして個別にプリコンパイルする必要があります。

私の改訂したCSSSplitterGistが、このソリューションを採用するのに十分なほど完全であることを願っています。

アップデート:

上記のCssSplitterの言及は、現在gemとしてリリースされています:https ://github.com/zweilove/css_splitter

于 2012-08-26T22:14:19.097 に答える
7

私が本番環境で使用しているソリューションは非常に単純で、自動化されていませんが、非常にうまく機能します。私にとって、これは当然のことだったので、おそらくあなたはすでにそれについて考えていて、それが気に入らなかったでしょう-いずれにせよ、ここに行きます:

私はあなたがsassを使用していると仮定しています、そうでなければ、私はあなたがすべきだと思います:)



まずapplication.css.scss、別のファイルに 分割します。例:application_a.css.scssapplication_b.css.scss



次にapplication.css.scssファイルで次を使用します。

@import "application_a"
@import "application_b"



3番目に、レイアウトテンプレートに、ファイル全体または両方の部分を含めます。

<!--[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。それ以外はすべて問題が発生します。

于 2012-08-26T11:23:58.170 に答える