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.