Rewrite CSS

Configuration

The 'Rewrite CSS' filter is enabled by specifying:

Apache:
ModPagespeedEnableFilters rewrite_css
Nginx:
pagespeed EnableFilters rewrite_css;

in the configuration file. To enable fallback rewriting on CSS we cannot parse, also specify:

Apache:
ModPagespeedEnableFilters fallback_rewrite_css_urls
Nginx:
pagespeed EnableFilters fallback_rewrite_css_urls;

Description

This filter parses linked and inline CSS, rewrites the images found and minifies the CSS. The filter works on CSS found in <style> blocks and <link> refs.

Many images are referenced from CSS rather than HTML. If rewrite_images, recompress_images, recompress_jpeg, recompress_png, recompress_webp, convert_gif_to_png, convert_jpeg_to_webp, convert_png_to_jpeg, or extend_cache are enabled this filter finds and rewrites those images, saving bytes and extending cache lifetimes.

The CSS parser cannot parse some CSS3 or proprietary CSS extensions. If fallback_rewrite_css_urls is not enabled, these CSS files will not be rewritten at all. If the fallback_rewrite_css_urls filter is enabled, a fallback method will attempt to rewrite the URLs in the CSS file, even if the CSS cannot be successfully parsed and minified.

Minification can drastically reduce the byte count in common CSS by stripping all comments and most whitespace and shortening color names. This filter can be used to avoid the extra step of minifying CSS by hand when constructing and maintaining a site. This practice reduces the payload size.

Example

For example, if the HTML document looks like this:

<html>
  <head>
    <style>
      body { background-image: url("foo.png"); }
      /* This comment will be stripped */
      #iddy, .anotherId {
        border: solid 1px #cccccc;
        padding: 1.2em;
        float: left;
        color:##ff0000;
      }
    </style>
    <link rel="stylesheet" type="text/css" href="extStyle.css">
  </head>
  <body>
    Wow, <div class="classy" id="iddy">
    CSS is <span>stylin'</span>.</div>
  </body>
</html>

With the following in extStyle.css:

  div.classy span, div.classy img {
    display: block;
    border: none !important;
    background: none !important;
  }

Then PageSpeed will rewrite it into:

<html>
  <head>
    <style>body{background-image:url(xfoo.png.pagespeed.ic.HASH.png}#iddy,#anotherId{border:solid 1px #ccc;padding:1.2em;float:left;color:red}</style>
    <link rel="stylesheet" type="text/css" href="I.extStyle.css.pagespeed.cf.HASH.css">
  </head>
  <body>
    Wow, <div class="classy" id="iddy">
    CSS is <span>stylin'</span>.</div>
  </body>
</html>

And the rewritten file I.extStyle.css.pagespeed.cf.HASH.css will contain:

  dif.classy span,div.classy img{display:block;border:none!important;background:none!important}

Online Example

You can see the filter in action at www.modpagespeed.com for CSS minification, cache-extending images in CSS, rewriting images in CSS and fallback rewriting of images in CSS.

Requirements

Only CSS referenced by <style> and <link> tags is rewritten. For example, style attributes of HTML elements are not rewritten. Enable rewrite_style_attributes to rewrite these as well.

Not all CSS3 or proprietary constructs are parsed. When unhandled syntax is present and the file cannot be parsed completely, the URLs in the CSS can still be rewritten by the fallback_rewrite_css_urls filter. However the CSS will not be minified.

Risks

CSS minification is considered moderate risk.

Specifically, there is an outstanding bug that the CSS parser can silently lose data on malformed CSS. This only applies to malformed CSS or CSS that uses proprietary extensions. All known examples have been fixed, but there may be more examples not discovered yet. Without this the risk would be low.

Some JavaScript code depends upon the exact URLs of resources. When we minify CSS we will change the leaf name of the file (although leave it in the same directory). This could break such JavaScript.

Troubleshooting

To troubleshoot why CSS is not minified, you can use the standalone binary css_minify_main. It's shipped with mod_pagespeed, so build it from source and then run:

  ./out/Release/css_minify_main FILENAME.css > REWRITTEN.css

The rewritten version is piped to stdout and the errors encountered are piped to stderr. These error messages should be helpful in figuring out what aspects of the CSS file could not be parsed.