Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: v1.0-stable
Fetching contributors…

Cannot retrieve contributors at this time

196 lines (139 sloc) 6.649 kB


Concisely generate CSS style rules within Javascript. Features:

  • standard "object literal"/JSON format with good editor support
  • nesting to DRY up stylesheets
  • color functions like darken and saturate
  • built-in macros for common CSS idioms like clearfix, rounded corners, drop shadows.
  • and all the plain old Javascript behavior: functions, data structures, looping, Math operations, etc.


All code is packaged into a single Javascript file download, csster.js. There are no external dependencies. The project itself is hosted on GitHub.

require('csster.js'); // however you manage dependencies{
  h1: {
    fontSize: 18,
    color: 'red'


Result, inserted in DOM automatically at the bottom of the <head> element:

<style type="text/stylesheet">
h1 {
font-size: 18px;
color: red;

Format of CSS Rules

The style method accepts CSS rules passed either as arrays or hashes, arrays just being a way to order the hashes. For example:

    ul: {
      margin: 5,
      padding: 0,
    'ul li:first': {
      paddingLeft: 20px

Note that

  • property names are automatically converted to hyphenated format from camelcase, so in many cases you can omit the quotation marks. ('float' needs to quoted since it's a reserved word.)
  • all raw numbers are assumed to be "pixels" (or "px"), and rendered as such.
  • any sort of selectors are allowed... they are just passed through to the stylesheet.


Csster supports nesting of rules to keep things more concise:

    ul: {
      margin: 5,
      li: {
        paddingLeft: 20,
        '&:hover': {
          color: 'red'

The "li" property in this case might be a selector or might be a property name. A list of valid property names is used to identify properties right now, and otherwise it's considered a sub-selector.

Csster supports SASS's "&" operator, to indicate that the selector should be combined with the parent selector. Instead of the default "any descendent" space character being inserted, no space is inserted.

Combined rules (with commas) are expanded as expected, so nested rules with commas have their parents expanded.

By default, rules with multiple '#'s are simplified. For example, '#a #b #c' becomes '#c'. Usually this is what you will want, but if you need the specificity you can turn this off with Csster.shortCircuitIds = false


Most manipulations will fall into Javascript's language support, as far as any math or looping. Use Javascript to write necessary functions.

function/color.js contains SASS-like color functions:

  • "#ab342c".darken(%) -- make color darker by given percent
  • "#ab342c".lighten(%) -- make color lighter by given percent
  • "#ab342c".saturate(%) -- make color more saturated by given percent. To desaturate, use negative values for the percent. Note that "#ab342c".saturate(-100) renders in grayscale.

There are also color conversion routines if you want to build your own manipulation.

  • "#ab342c".toRGB()
  • "#ab342c".toHSL()
  • Csster.hslToHexColor(h,s,l)

Opacity is currently not supported by the color model.

Macros using "has" key

There are a host of pre-made macros that may be useful:

  • roundedCorners(radius) -- add rounded corners on all sides
  • roundedCorners(side, radius) -- add rounded corners on specified side: 'top', 'left', 'bottom' or 'right'
  • roundedCorners(corner, radius) -- add rounded corners to a specified corner: 'tl', 'tr', 'bl' or 'br'
  • phark(width, height, img, imgXPosition=0, imgYPosition=0) -- standard phark image replacement with optional background image offset.
  • boxShadow([xoffset, yoffset], radius, color)
  • verticalCentering(height) and horizontalCentering(width) -- center using the top 50% / margin-top -width/2 technique. See
  • clearfix() -- standard clearfix

To "mix these in", use the "has" key:

    'div#featured_box': {
      backgroundColor: '#394c89',
      has: roundedCorner(5)

Multiple macros can be included by making that a list, eg. has: [roundedCorners(5), dropShadow()].

It's all Javascript, so macros and more complex functions are easy to write. To mix in a set of values, create a function that returns a hash of values, for example:

    function roundedCorners(radius) {
        return {
            '-webkit-border-radius': radius,
            '-moz-border-radius': radius,
            'border-radius': radius

A macro's properties will be overwritten by properties within including selector (or later included macros), similar to how the cascade takes the last defined value.



The design was driven by the specs.


  • decompile existing stylesheets
  • jQuery rules
  • Fix license
  • Better name


This project comes from my frustration of trying to build standalone Javascript widgets. Web projects always involve the combination of HTML DOM, CSS and Javascript. It's often simpler to generate the necessary DOM within your Javascript, removing any coupling (and a simpler calling convention) to a specific web page. But most widgets have certain style rules. To avoid any coupling with the CSS at all, styles can be included inline, but these gets bulky and hard to read. The "rule" nature of CSS is nice. So widgets then have a Javascript and CSS component. Wouldn't it be nice, though, to remove that CSS component.

With the advent of SASS, the coupling is even more complicated, as now there's some other tool completely unrelated to your component, written in some other language. Wouldn't a unified approach be nice?

Similar projects


Copyright (c) 2010 Andrew J. Peterson All Rights Reserved.

Jump to Line
Something went wrong with that request. Please try again.