Rozwiązanie rails asset pipeline dla IE 4096 selector / stylesheet limit

Problem

Dokumentacja obsługi IE firmy Microsoft wyjaśnia, że w Internet Explorerze 6-9:

  1. wszystkie znaczniki stylu po pierwszych 31 znacznikach stylu nie są stosowane.
  2. wszystkie reguły stylu po pierwszych 4095 reguł nie są stosowane.
  3. na stronach, które używają reguły @import do ciągłego importowania zewnętrznych arkuszy stylów, które importują inne arkusze stylów, arkusze stylów o głębokości większej niż trzy poziomy są ignorowane.

Istnieje wiele dowodów na ten problem z skrypt dema . Zobacz też Bless .

Potrzebne rozwiązanie

Potrzebujemy sposobu na podzielenie skompilowanych arkuszy stylów generowanych przez Sprockets w potoku zasobów, aby utrzymać maksymalną liczbę selektorów poniżej 4096 i połączyć się z nimi w HTML wdrożonej aplikacji Rails. Jak możemy przekazać skompilowane wyjście przetworzonych zasobów (w szczególności arkuszy stylów) jako argument do metody, która może następnie zmodyfikować akta?

Zobacz poniższe próby na początek. Jeśli ktoś mógłby mi pomóc znaleźć sposób na uruchomienie (lub zupełnie nowe rozwiązanie), byłoby fantastycznie!

Istniejące próby rozwiązania

  • Bless został stworzony, aby rozwiązać ten problem, dzieląc arkusze stylów, aby utrzymać maksymalną liczbę selektorów na arkuszu poniżej limitu. Bless działa na serwerze w node.js. Nie widziałem jeszcze rubinowego odpowiednika. Eric Fields próbował serwować zasoby skompilowane za pomocą compass do Bless (uruchamiane w węźle), ale to rozwiązanie zależy od Compass obsługującego kompilację zasobów i dlatego nie wydaje się działać z potokiem zasobów. zauważ, że zamiast linkowania do wielu arkuszy stylów, Bless dodaje polecenia @include do pierwszego arkusza, co może być sposobem, aby uniknąć dotykania znaczników.

  • Kiedy Christian Peters (@crispy) odkrył ten problem , zaimplementował splitter Jak Bless to również przekazało wyjście Compass do niestandardowego modułu, który działał świetnie przed Rails 3.1. Później zaadaptował swój splitter z zębatką do integracji z szynami Asset pipeline . Próbowałem zaimplementować nowy kod, ale wydaje się, że nie działa automatycznie (choć splitter działa dobrze, gdy jest wywoływany ręcznie w konsoli).

Informacje pokrewne

Aby uzyskać więcej informacji na temat limitów CSS w IE 6-9, zobacz te powiązane pytania:

Author: Community, 2012-08-26

2 answers

mamy zautomatyzowane (choć jakoś niezręczne) rozwiązanie pracujące w produkcji dla aplikacji Rails 3.1 z asset pipeline w miejscu. Ryan już odniósł się do rozwiązania w swoim pytaniu, ale staram się wymyślić bardziej wyczerpującą odpowiedź.

[[7]}asset pipeline przewodzi aktywa za pomocą różnych silników zębatych.

Więc możesz mieć np. {[3] } który biegnie przez silnik Zębatki ERB, a następnie przechodzi do silnika Zębatki Sass itp. Ale zawsze jest to jeden plik w i jeden plik.

W tym specjalnym problemie chcemy mieć 1 plik przychodzący i n plików wychodzących. Nie znaleźliśmy sposobu, aby to było możliwe dzięki zębatkom. Ale znaleźliśmy obejście:

Podaj ie.css.sass, który zawiera pełny arkusz stylów i ie_portion2.css.sass.split2, który importuje tylko pełny ie.plik css:

//= include 'ie.css'

Dla rozszerzenia pliku split2 rejestrujemy Silnik zębaty:

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

Podczas oceny aktywów z rozszerzeniem split2 przekazujemy jego zawartość do CssSplitter i polecić mu wyodrębnić część 2 (>4095 selektorów):

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

To zadziała również dla dalszych części (split3, ...).

Splitter CSS rozpoznaje poprawne miejsca, w których arkusze stylów mogą być dzielone na części z mniej niż 4096 selektorami i zwraca żądaną część.

Wynikiem jest ie_portion2.css, który musisz połączyć w głowicy i wstępnie skompilować osobno.

Mam nadzieję, że mój poprawionyCSS Splitter Gist jest kompletny wystarczy, by zastosować rozwiązanie.

Update:

Wspomniany wyżej CssSplitter został wydany jako klejnot: https://github.com/zweilove/css_splitter

 10
Author: crispy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-26 22:35:20

Rozwiązanie, którego używam w produkcji jest bardzo proste, nie zautomatyzowane, ale działa bardzo dobrze. Dla mnie było to oczywiste, więc może już o tym myślałeś i nie podobało ci się - tak czy inaczej, zaczynamy: {]}

Zakładam, że używasz sass, jeśli nie, to myślę, że powinieneś :)



najpierw Podziel swoje application.css.scss w osobne pliki, np.: application_a.css.scss i application_b.css.scss



drugi , w twoim application.css.scss pliku, użycie:

@import "application_a"
@import "application_b"



Po Trzecie , w szablonie układu, Dołącz kompletny plik lub obie części:

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

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

Side note: Nie Generuj plików manifest arkusza stylów za pomocą potoku zasobów, rób to za pomocą sass i instrukcji @import, Wszystko inne będzie prowadzić do problemów.

 7
Author: doesterr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-26 11:23:58