Module: CSSMin

Defined in:
lib/cssmin-ebtd.rb

Overview

CSSMin

Minifies CSS using a fast, safe routine adapted from Julien Lecomte’s YUI Compressor, which was in turn adapted from Isaac Schlueter’s cssmin PHP script.

Author

Ryan Grove ([email protected])

Version

1.0.2 (2008-08-23)

Copyright

Copyright © 2008 Ryan Grove. All rights reserved.

License

New BSD License (opensource.org/licenses/bsd-license.php)

Website

github.com/rgrove/cssmin/

Example

require 'rubygems'
require 'cssmin'

File.open('example.css', 'r') {|file| puts CSSMin.minify(file) }

Class Method Summary collapse

Class Method Details

.minify(input) ⇒ Object

Reads CSS from input (which can be a String or an IO object) and returns a String containing minified CSS.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/cssmin-ebtd.rb', line 52

def self.minify(input)
  css = input.is_a?(IO) ? input.read : input.dup.to_s

  # Remove comments.
  css.gsub!(/\/\*[\s\S]*?\*\//, '')

  # Compress all runs of whitespace to a single space to make things easier
  # to work with.
  css.gsub!(/\s+/, ' ')

  # Replace box model hacks with placeholders.
  css.gsub!(/"\\"\}\\""/, '___BMH___')

  # Remove unnecessary spaces, but be careful not to turn "p :link {...}"
  # into "p:link{...}".
  css.gsub!(/(?:^|\})[^\{:]+\s+:+[^\{]*\{/) do |match|
    match.gsub(':', '___PSEUDOCLASSCOLON___')
  end
  css.gsub!(/\s+([!\{\};:>+\(\)\],])/, '\1')
  css.gsub!('___PSEUDOCLASSCOLON___', ':')
  css.gsub!(/([!\{\}:;>+\(\[,])\s+/, '\1')

  # Add missing semicolons.
  css.gsub!(/([^;\}])\}/, '\1;}')

  # Replace 0(%, em, ex, px, in, cm, mm, pt, pc) with just 0.
  css.gsub!(/([\s:])([+-]?0)(?:%|em|ex|px|in|cm|mm|pt|pc)/i, '\1\2')

  # Replace 0 0 0 0; with 0.
  css.gsub!(/:(?:0 )+0;/, ':0;')

  # Replace background-position:0; with background-position:0 0;
  css.gsub!('background-position:0;', 'background-position:0 0;')

  # Replace 0.6 with .6, but only when preceded by : or a space.
  css.gsub!(/(:|\s)0+\.(\d+)/, '\1.\2')

  # Convert rgb color values to hex values.
  css.gsub!(/rgb\s*\(\s*([0-9,\s]+)\s*\)/) do |match|
    '#' << $1.scan(/\d+/).map{|n| n.to_i.to_s(16).rjust(2, '0') }.join
  end

  # Compress color hex values, making sure not to touch values used in IE
  # filters, since they would break.
  css.gsub!(/([^"'=\s])(\s?)\s*#([0-9a-f])\3([0-9a-f])\4([0-9a-f])\5/i, '\1\2#\3\4\5')

  # Remove empty rules.
  css.gsub!(/[^\}]+\{;\}\n/, '')

  # Re-insert box model hacks.
  css.gsub!('___BMH___', '"\"}\""')

  # Put the space back in for media queries
  css.gsub!(/\band\(/, 'and (')

  # Prevent redundant semicolons.
  css.gsub!(/;+\}/, '}')

  css.gsub!(/(\W)border:none(\W)/, '\1border:0\2')
  css.gsub!(/(\W)background:none(\W)/, '\1background:0\2')

  css.strip
end