Created
August 8, 2011 10:22
-
-
Save ChristianPeters/1131536 to your computer and use it in GitHub Desktop.
Split CSS files so that there are no more than a given number of selectors in one style sheet. This is a tool to cope with Internet Explorer's limitation of max. 4095 selectors per stylesheet.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rake' | |
require 'css_splitter' | |
desc 'split css files' | |
namespace :css do | |
task :split do | |
infile = ENV['infile'] || raise("missing infile") | |
outdir = ENV['outdir'] || File.dirname(infile) | |
max_selectors = ENV['max_selectors'] || 4095 | |
CssSplitter.split(infile, outdir, max_selectors) | |
end | |
task :count_selectors do | |
css_file = ENV['css_file'] || raise("missing css file") | |
CssSplitter.count_selectors(css_file) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CssSplitter | |
def self.split(infile, outdir = File.dirname(infile), max_selectors = 4095) | |
raise "infile could not be found" unless File.exists? infile | |
rules = IO.readlines(infile, "}") | |
return if rules.first.nil? | |
charset_statement, rules[0] = rules.first.partition(/^\@charset[^;]+;/)[1,2] | |
return if rules.nil? | |
# The infile remains the first file | |
file_id = 1 | |
selectors_count = 0 | |
output = nil | |
rules.each do |rule| | |
rule_selectors_count = count_selectors_of_rule rule | |
selectors_count += rule_selectors_count | |
# Nothing happens until the selectors limit is reached for the first time | |
if selectors_count > max_selectors | |
# Close current file if there is already one | |
output.close if output | |
# Prepare next file | |
file_id += 1 | |
filename = File.join(outdir, File.basename(infile, File.extname(infile)) + "_#{file_id.to_s}" + File.extname(infile)) | |
output = File.new(filename, "w") | |
output.write charset_statement | |
# Reset count with current rule count | |
selectors_count = rule_selectors_count | |
end | |
output.write rule if output | |
end | |
end | |
def self.count_selectors(css_file) | |
raise "file could not be found" unless File.exists? css_file | |
rules = IO.readlines(css_file, '}') | |
return if rules.first.nil? | |
charset_statement, rules[0] = rules.first.partition(/^\@charset[^;]+;/)[1,2] | |
return if rules.first.nil? | |
rules.inject(0) {|count, rule| count + count_selectors_of_rule(rule)}.tap do |result| | |
puts File.basename(css_file) + " contains #{result} selectors." | |
end | |
end | |
def self.count_selectors_of_rule(rule) | |
rule.partition(/\{/).first.scan(/,/).count.to_i + 1 | |
end | |
end |
Hi,
Has anyone overcome the issue of media queries that t22james has ran into? This issue seems like a mayor bug and reason not to use this script to me, but since it's about 4 years old by now, maybe someone has already fixed it.
Thanks in advance
I'm having same media query split problem.as @t22james
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello.
I'm not familiar with ruby, but i tried to fix this tool to suit my needs:
IE have limits not only on selector count but also *.css file size, sometimes fat stylesheets files can throw errors in IE (something like: Out of memory at line XXX.) So we need to split first 4095 selectors in separate file too and include them instead of full css file.
for example:
If you have same issues check my gist, it works perfect:
https://gist.github.com/todesstoss/1c3ac8310de7714a65e6
Thanks.