Skip to content

sndrs/postcss-atomised

Repository files navigation

postcss-atomised

npm version Build Status Coverage Status Dependency Status Dependency Status devDependency Status

This is probably not stable. It was initially developed for use on the Guardian website, but it feels like it's the wrong solution to the problem of bloat + complexity. Leaving it here in case anyone finds it useful or we pick it up again.


PostCSS plugin that atomises a standard set of CSS, and provides a json map from the original classes to the atomised ones.

Enables you to write CSS in an insolated, super-modular fashion without worrying about the bloat of duplication (the only way you could serve a smaller stylesheet would be to use fewer styles).

Example

Take your stylesheet…

/* original.css */
.one {
    background-color: red;
    margin: 1rem;
}
.two {
    background-color: red;
    margin-top: 1rem;
}
@media (min-width: 100px) {
    .two:hover {
        background-color: hotpink;
    }
}

Pass it through the plugin…

// load the original CSS file and atomise it

import {readFileSync} from 'fs';

import postcss from 'postcss';
import atomised from 'postcss-atomised';

const css = readFileSync('./original.css', 'utf8');
const options = {};

postcss([atomised(options)]).process(css).then(result => {
    // do something with `result`
});

result.css is a String containing the atomised CSS:

.a { background-color: red; }
.b { margin-top: 1rem; }
.c { margin-right: 1rem; }
.d { margin-bottom: 1rem; }
.e { margin-left: 1rem; }
@media (min-width: 100px) {
    .f:hover { background-color: hotpink; }
}

You now also have a file called atomised-map.json in cwd.

// atomised-map.json
{
  "one": ["a", "b", "c"," d", "e"],
  "two": ["a", "b", "f"]
}

This can be used to transform your templates.

<div class="one"></div>
<div class="two"></div>

into…

<div class="a b c d e f"></div>
<div class="a c g h"></div>

Options

Type: Object | Null

No options are required. By default, a file called atomised-map.json will be written to cwd containing the atomised JSON map.

options.mapPath

Type: (String | Null) optional

Alternative location for the atomised JSON map to be saved. null will prevent the output being written to disk.

options.mapHandler

Type: (Function) optional

Callback function that receives one arguement – the JSON map object.

Restrictions

  • only single class selectors can be atomised (other selectors will pass straight through)
  • multiple/duplicate and pseudo selectors/elements are fine
Selector Ok
.a .b { }
.a.b { }
a { }
a b { }
#a { }
a[b] { }
a > b { }
a + b { }
a ~ b { }
*
.a:b { }
.a, .b { }
.a { } .a { }
.a:hover { }

Development

Run npm start to run the test runner in watch mode, or npm test for a one-off. Node 6 or greater is needed for development.

Node.js 0.*

Node 4 or greater is needed to use the plugin.