More on CSS Renaming - google/closure-stylesheets GitHub Wiki

Introduction

Before reading this article, you should have already read the section on renaming from the Closure Stylesheets overview. This article explains more of the options related to CSS renaming.

Renaming Options

There are two command-line flags of interest with respect to CSS renaming:

Each of these command line flags supports several different values. This is done to accommodate different styles of development.

--rename Option

The --rename flag determines the algorithm that Closure Stylesheets uses to rename your CSS classes. The options are as follows:

NONE

NONE should be used when no renaming should be done. This is the default option.

DEBUG

DEBUG should be used when debugging CSS renaming. Each CSS class is trivially renamed by taking each part of the class name (where parts are delimited by hyphens) and appending a trailing underscore.

This mode is helpful as a "debug" mode of sorts to catch cases where a class name is not wrapped with goog.getCssName(). For example, if you use DEBUG renaming in development and you notice that the style of a DOM element does not look right, then you should take a look to see what its CSS class name is. If you notice that it does not contain any underscores but you expected it to be renamed, then you should be able to track down the reference to the class name in your code and add the appropriate goog.getCssName() wrapper. If NONE renaming were used, then this bug would not reveal itself in development, and if CLOSURE renaming were used, it would take more work to reverse-map the obfuscated class name in the DOM to the original class name in your code.

CLOSURE

CLOSURE should be used when minifying class names for production. Each CSS class name is split into parts (as delimited by hyphens), and then parts are renamed using the shortest available name. Parts are renamed consistently, so if .foo-bar is renamed to .a-b, then .bar-foo will be renamed to .b-a.

This focus on splitting on hyphens stems from the fact that the goog.getCssName() function in the Closure Library has an optional second argument that is appended using a hyphen. For example, both of the following could be used to construct the CSS class .foo-bar:

// Using the single-argument form:
goog.getCssName('foo-bar');

// Using the two-argument form:
goog.getCssName(goog.getCssName('foo'), 'bar');

Both of the above expressions will yield the string 'foo-bar' in the absence of any renaming map. Because the classes in the stylesheet are renamed without any knowledge of how the class names will be constructed in the JavaScript code, it must use a renaming scheme that supports both forms of construction.

For historical reasons, the second argument to goog.getCssName() is appended using a hyphen. This is somewhat unfortunate because hyphens are also frequently used as visual separators in long CSS names, making it impossible to distinguish which parts come from the "base" name and which parts come from the "suffix" by looking at the name alone.

This is unfortunate because it often results in slightly suboptimal CSS. For example, if a stylesheet has only one CSS class named .foo-bar that is exclusively referenced via goog.getCssName('foo-bar') in JavaScript code, it will be renamed to .a-b rather than .a in both the CSS and JS. One workaround is to adopt the convention of using an underscore as a visual separator rather than a hyphen. That is, name your class .foo_bar if it is referenced exclusively via goog.getCssName('foo_bar') in your JavaScript code. This will result in a single-letter renaming, as desired.

Note that although non-ASCII characters are allowed in CSS class names, which could be used to produce class names with fewer characters, this generally results in less efficient gzip compression of the minified stylesheet. For this reason, the class names produced by CLOSURE renaming are limited to alphanumeric ASCII characters.

--output-renaming-map-format Option

The renaming map produced by Closure Stylesheets often needs to be consumed by another tool, such as the Closure Compiler. Closure Stylesheets provides several output formats to provide straightforward integration with the Closure Tools, while also providing the opportunity for you to build your own tools on top of Closure Stylesheets.

CLOSURE_COMPILED

CLOSURE_COMPILED should be used when compiling JavaScript with the Closure Compiler in either SIMPLE or ADVANCED mode. When CLOSURE_COMPILED is specified, the output is a JSON map of renaming information wrapped in a call to goog.setCssNameMapping(), such as:

goog.setCssNameMapping({
  "foo": "a",
  "bar": "b"
});

This file should be passed as an input to your compilation. The Compiler will remove this call to goog.setCssNameMapping() and use the object literal that is passed to it as the basis for replacing all calls to goog.getCssName() in the compiled code.

CLOSURE_UNCOMPILED

CLOSURE_UNCOMPILED should be used with uncompiled Closure Library code. When CLOSURE_UNCOMPILED is specified, the output is a JSON map of renaming information assigned to the global variable CLOSURE_CSS_NAME_MAPPING, such as:

CLOSURE_CSS_NAME_MAPPING = {
  "foo": "a",
  "bar": "b"
};

This file should be loaded via a <script> tag before base.js is loaded for the Closure Library. This is because base.js checks to see whether the global CLOSURE_CSS_NAME_MAPPING variable is declared, and if so, uses its value as the renaming data for goog.getCssName(). This ensures that the mapping data is set before any calls to goog.getCssName() are made.

JSON

JSON should be used when building a tool that wants to consume the renaming map data. When JSON is specified, the output is a pure JSON map, such as:

{
  "foo": "a",
  "bar": "b"
}

Currently, JSON is the default value for the --output-renaming-map-format option.

PROPERTIES

PROPERTIES should be used as an alternative to JSON if, for some reason, your toolchain does not have a JSON parser available. When PROPERTIES is specified, the output is a .properties file formatted as key=value pairs without any comments, such as:

foo=a
bar=b

This format is extremely strict and simple so that it should be easy to write a custom parser for it in whatever language you are using to process the renaming map data.

⚠️ **GitHub.com Fallback** ⚠️