Rewrite of cujo's cssx library for extending css in older browsers (requires an AMD loader)
JavaScript CSS
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


cssx (Cujo Style Sheet eXtender)

***** This project is no longer being maintained! *****

If you are looking for an AMD plugin for loading css, check out these:

link! - loads css files in a link element
css! - loads via link element or embeds css text into javascript and injects a style tag

Both of these are maintained in the cujoJS curl.js repo:

If you are interested in an AMD plugin that shims CSS3 features for older browsers (and more), check out Kris Zyp's xstyle:

cssx: current version: 0.1

The following shims modules are working:
 * boxOffsets (IE6)
 * childSelector (.parent > .chid) (IE6)
 * comboSelector (.class1.class2) (IE6)
 * hover (.anything:hover) (IE6)
 * ieOpacity (IE6-8)
 * opacity (makes future css3 "opacity" work) (all non-IE browsers)
 * inlineBlock (IE6 and 7)
 * minmax (min-width, max-width, min-height, max-height) (IE6)
 * scrollbar (adds a scrollbar-width unit of measurement) (all browsers)
 * @imported stylesheets are now processed!

What's not working:
 * attribute selectors (e.g. input[type="checkbox"])
 * the UA sniffs to load bundles are not complete
 * media types are fixed at "all", "screen", and "handheld"

 * more shims: transtions, box-sizing,
 	:first-child, :last-child
 * Kris Zyp's Xstyle extensions need to be added
 * try to get Kris Zyp's fast-parse mechanism working


What is cssx?

Cssx is an AMD-compliant plugin that loads and augments css files. It's
an important part of the cujo web app framework, but can be used
independently of any other cujo micro-library. Cssx only requires an
AMD-compliant module loader, such as RequireJS, Backdraft's loader, or
curl.js (another awesome cujo micro-library).

If you want to just use the css-loading capabilities of cssx, you can
simply copy the css.js file into your project. It does not rely on any other
files in this repo. css.js requires the use of an AMD-compliant module
loader just like cssx does. More notes about using css.js are in the section 
"How do I just use css.js in my RequireJS or curl.js project?" (below).


Why would you want to augment css files?

Mainly, to provide fixes for browsers that don't support CSS 3 or CSS 2.1.
Cssx has it's own plugins. These plugins modify css in various ways, such as:

 1) convert opacity and rgba to something that works in IE, e.g.:
    opacity:0.1; to filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=10);
 2) implement "box offset positioning" in IE6
 3) implement advanced selectors in IE 6&7, e.g.:
    input[type=checkbox], .class1.class2, .parent > .child
 4) automatically convert css3 properties to vendor-specific properties, e.g.:
    transition:opacity 1s ease; to -webkit-transition:opacity 1s ease;
 5) automatically convert machine-specific measurements, e.g.:
 	margin-right: -cssx-scrollbar-width; to margin-right: 15px;

All of the above (and several others) are already implemented and work
dynamically (not statically like when using Selectivizr)! Because cssx is
plugin-based, you can create and add your own cssx plugins.


Doesn't run-time augmentation of css take up valuable load time?

Yes. It does. But probably not as much as you think. It takes a few
milliseconds to process a reasonably-sized css file. cssx provides several
configuration options to help streamline the parsing process.

Current work on AMD is focused on building optimized bundles of javascript
for each browser.  This is called User Agent Profiling. UA Profiling also
extends to AMD plugins like cssx.  UA Profiling will allow css augmentation
to run on the server, rather than in the browser, eliminating the expensive
text parsing.

cujo.js's build tool, cram (Cujo Resource AsseMbler), is only in the proof-
of-concept stages. We expect it to be ready by mid 2011.


How do I start using cssx?

To start using cssx, just copy (or clone) the src/cssx folder into your project
and map one of your AMD loader paths to it. There are several ways to map your
loader paths. Go RTFM if you want to get the intimate details. In summary, you
should map your loader's baseUrl to a common folder to all your javascript
modules (including plugins such as cssx), if a common folder exists. Then,
create path configuration options for any module roots that aren't peers within
the baseUrl folder. Here's a simple example:

// this is just one way to set the configuration for RequireJS or curl.js:
require = {
	baseUrl: 'js/', // maps to the js folder that is a peer to this page
	paths: {
		myApp: 'myCompany/myApp', // maps to js/myCompany/myApp/
		cssx: '../libs/cssx' // maps to libs/cssx
		// Note: libs and js are peer folders

Once you've got the paths configured correctly, you can start referencing the
cssx plugin in your code.  Typically, you'll do this in define() calls. By
convention, you should invoke the plugin by using a prefix with a complete path
to the plugin. Prefixes are delineated by a ! symbol in the module name. (CSS
files are considered resources by AMD loaders, but have the same syntax as

		'myApp/moduleA', // a javascript module dependency
		'text!templates/myTemplate.html', // example usage of the text plugin
		'cssx/cssx!styles/moduleA.css' // our css file!
	function (moduleA, template, cssxDef) {
		// code some awesomeness here

In this example, the stylesheet, moduleA.css is loaded, parsed, and augmented
by cssx before the callback function is executed.  When the callback function
executes, it is handed an object, cssxDef, which -- except for tinkerers and
the curious -- is not of much use.  It contains a reference to the original
<LINK> element inserted as well as a possible <STYLE> element if additional
rules were needed to implement fixes for the current browser. Any other
properties of this object are subject to change in future releases.

Even if the returned object is not of direct use, it is extremely useful to
know that the styles in your stylesheet are:

 1) ready for immediate use (it's ok to display content now)
 2) converted to work with the current browser

Note: the .css extension is optional in curl.js, but appears to be necessary in
current versions of RequireJS (version 0.22).

Typically, you don't want to scan every css file for every possible browser fix
(although maybe you do :D ). There are several ways to fine-tune the set of
cssx plugins that get loaded. The simplest way to do this from javascript is
via plugin suffixes. These are appended to the module/resource name in the
dependency list:

define(['cssx/cssx!myStyles.css!ignore:inlineBlock,boxOffsets'], callbackFunc);

The suffixes are again delineated by the ! symbol, but appear after the module
name. In this example, cssx has been instructed to ignore any inline-block or
box offset fixes. In fact, it won't even attempt to load the cssx plugins for
those. See the section, "How can I optimize cssx to only scan my css files for
certain fixes?" for more details about optimizing cssx.


What CSS 2.1 and CSS 3 features does cssx fix?

TODO: Complete list


How can I optimize cssx to only scan my css files for certain fixes?

TODO: Show auto and manual modes and all three methods of specifying options


Is there any advantage to using cujo's curl.js with cssx?

Yes. Unlike other AMD loaders, curl.js passes javascript promises to its
plugins rather than just a callback function. curl.js does this in a backward-
compatible way. This allows cssx plugins to proactively stop the loading
process in response to errors. curl.js can also directly notify plugins that
an exception has occurred elsewhere so the plugins can clean-up accordingly.


How do I just use css.js in my RequireJS or curl.js project?

The css.js file in this project can be used independently of the rest of cssx.
If you're just interested in loading css files in your AMD-based project, this
is all you need!

First, copy css.js into your project. It's simplest if you copy it into a cssx
sub-folder of your javascript folder.  For instance, if your web app's
javascript is in the /js/ folder, then place css.js into the /js/cssx/ folder:


If the baseUrl of require.js or curl.js points to the /js/ folder, then you
should be able to start specifying css resources in your require() and define()
calls like this:

require(["cssx/css!path/to/css/file.css"], funcToRunAfterCssIsReady);

If you're not familiar with AMD plugin notation, then it's time to go RTFM. :)
In short, everything before the ! is a path to the plugin. The path is rooted
at the baseUrl configuration parameter of the loader (just like other
javascript modules).

The .css extension is optional in curl.js, but seems to be necessary in
current versions of RequireJS (last checked in version 0.22).

By default, css.js will load and wait for the css file to be applied to the
document before calling your callback function.  In the example above, the css
rules of the file.css stylesheet will be fully functional before the function,
funcToRunAfterCssIsReady, is executed.

For a more complete example, here's another typical use of a require() call:

		"myApp/appLoader", // the main javascript module
		"cssx/css!common/css/base.css", // some base css file (resets, etc.)
		"cssx/css!myApp/css/appTheme.css", // an app-specific set of overrides
		"text!myApp/pageTemplate.html" // the main template for the page
	function (loader, base, theme, template) {
		   in here:
		   loader refers to your main javascript module
		   base refers to the <LINK> that refers to base.css
		   theme refers to the <LINK> that refers to appTheme.css
		   template contains the text of the page template in pageTemplate.html

You'll probably won't want to do anything with the <LINK> elements that
are returned to your callback function, but they're provided just in case. :)

If you don't want to write-out the full path of the plugin prefix ('cssx/css!')
and would rather just write 'css!', then you can either move the css.js file up
one folder level or give the loader a hint where to find css.js. Both curl.js
and RequireJS will accept a paths configuration option. There are several ways
to specify the paths option, but the following works with both:

		baseUrl: 'js/', // set this to the root of your paths
		paths: {
			'css' : 'cssx/css'
		// place your other dependencies here
		'css!common/css/base.css' // look ma, no cssx path in my prefix!
	function (/* dependencies */) {
		// do something really cool here


How do I get assistance using cssx?

Discussion group coming soon.