Python CSS Shrinker for WordPress

This isn't really specific to WordPress, but it preserves the first comment for WordPress theme management, WordPress is awesome, and I'm specifically using this for WordPress style sheets, so I'm making the connection.

I wrote this script to condense my style sheets into smaller files for faster download times. I'm all about customer service here.

And it's pleasing to me to distill the CSS into a purer essence and reduce network overhead. (Not that the throngs of visitors to this site are noticeably plugging the tubes.)

One benefit of using compression this way is that I can be more liberal in my stylesheet comments, knowing they won't burden the "production" .css file delivered to my patrons.

I didn't go for maximum shrinkage, but this provides sufficient minification for my tastes. Read below for additional commentary and caveats.

(I'm putting this in the public domain. Use at your own risk!)

css_shrinker.py

#!/usr/bin/python3

import sys
import re

css = open(sys.argv[1], 'r').read()
unshrunk_size = len(css)

# save first comment which wordpress needs to display theme info
if css.strip()[:2] == '/*':
	hdr_end = css.find('*/') + 2
	header_comment = '%s\n' % css[:hdr_end]

# remove comments
css = re.sub(r'(?s)/\*.+?\*/', '', css)

# collapse whitespace
css = re.sub(r'\s+', ' ', css.strip())

# remove whitespace around operators, groupings, etc.
css = re.sub(r'\s?(:|;|,|>|\(|\)|{|})\s?', r'\1', css)

# add one newline per selector to avoid one huge line
css = css.replace('}', '}\n')

css = header_comment + css
print(css)

sys.stderr.write('unshrunk = %d chars\n  shrunk = %d chars\n' %
                 (unshrunk_size, len(css)));

This applies to my personal experience with my own style sheets. It doesn't take into account the official CSS standard and might break valid style sheets that don't match my simple assumptions.

The script will certainly break workarounds that rely on comments. Here's another Python script that preserves one IE comment hack. That script also tries to do more with things like removing leading zeros in values like 0.5em, shortening colors like #ffffff into #fff, and other things that I don't understand.

I opted to keep my code as simple as possible and mainly worked on removing comments and most whitespace, which covers most of the shrinkable opportunities. I saved 25% on this site's current stylesheet and almost 50% on another one I'm working on that has more comments. (Of course, by the time you read this and click on that link, maybe I've gone back to a non-zipped style sheet.)

Here's a sample of the minified code:

a{color:blue;text-decoration:none;}
a:hover{color:#00b900;text-decoration:underline;}
img{border:0;}
p{margin:1em 0;padding:0;}
.page-header{margin-top:.6em;font-size:1.75em;}
h1{font-size:1.5em;text-align:left;margin:0;padding:0;}
h2,h3,h4{font-weight:bold;margin:1em 0;padding:0;}
h2{font-size:1.4em;}
h3{font-size:1.1em;}
h4{font-size:1em;font-style:italic;}

To work with the files, I renamed my current style.css to style-working.css in source control to preserve the history of the file, and now run css_shrinker.py style-working.css > style.css to create the compressed file.

If doing a lot of work on the .css locally, then I might change my local header.php to point to the "working" stylesheet and avoid having to keep running the compression script to see changes. (Leading to the inevitable day when I'll move the modified header.php file to production and style-working.css isn't there...)

If you enjoyed this article, please subscribe for free!
Via the atom or rss feed, or enter your email address to get updates when new entries are posted:
(Your email will not be shared nor used for anything other than sending new posts. See the policies page for more about subscriptions and privacy.)

You can skip to the end and leave a response. Pinging is currently not allowed.

No comments yet.

You can follow any responses to this entry through the
comments feed.

Say Your Say

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

By submitting your comment here, you agree to license it under the same Creative Commons Attribution-ShareAlike 3.0 License as the movingtofreedom.org web site. Please see policies for more information about comments and privacy.