css-node
a fast nodejs css pre-processor that lets you use javascript to create css


Documentation
About
css-node is a zero dependency highly extendable object oriented css pre-processor that uses
valid javascript to construct css.
The goal of css-node is to create a nodejs based css pre-processor that is only limited
by the capabilities of the nodejs javascript implementation and not confined to the limitations
of it's own api.
Index
Installation
npm
$ npm install css-node
git
$ git clone https://github.com/angeal185/css-node.git
Index
Setup
nodejs setup API
const { init } = require('css-node')
init()
const { build, watch } = require('css-node')
watch(function(file, stats){
console.log(file);
console.log(stats);
build(function(err, css){
if(err){return console.log(err)}
console.log(css)
})
})
command line only
commands valid within css-node dir
init app
$ npm run init
build css
$ npm run build
watch files and build on change
$ npm run watch
Index
Starters
css-node starters are css files that have been converted to js for use
in includes.
the starters could also be used as a basic reference for code format
css-node currently has starter include files for the following frameworks:
Index
Rules
- single quotes should only ever be used within double quoted strings
Index
Config
- the config file should be named
ncss and be within your working dir
- the config file can be in the format of either
.js or .json
- config values are constant throughout the execution of css-node
json example:
{
"dest": "/ncss/dist/app.min.css",
"globals": "/ncss/globals",
"mixins": "/ncss/mixins",
"helpers": "/ncss/helpers",
"sort_order": false,
"sort_properties": false,
"write_file": false,
"verbose": false,
"imports": [
"imported.css"
],
"includes": [
"/ncss/includes/index.js"
],
"watch": {
"delay": 0,
"interval": 5007,
"files": [
"/ncss/includes/index.js"
]
}
}
js example:
const config = {
"dest": "/ncss/dist/app.min.css",
"globals": "/ncss/globals",
"mixins": "/ncss/mixins",
"helpers": "/ncss/helpers",
"sort_order": false,
"sort_properties": false,
"write_file": false,
"verbose": false,
"imports": [
"imported.css"
],
"includes": [
"/ncss/includes/index.js"
],
"watch": {
"delay": 0,
"interval": 5007,
"files": [
"/ncss/includes/index.js"
]
}
}
module.exports = config
Index
Imports
- imports inclided in your config file at
config.imports will automatically
be included in your final build.
@import "example.css";@import "example2.css";
Index
Includes
within your includes is where your css is constructed.
There is no limitation to what you can or cannot do using javascript to build
your css, so long as the object exported, once executed, can be stringified into valid json.
- includes files have global access to globals, helpers and mixins
- you can require and use external modules from within any includes file
for example
let css = {
body: {
background: function(){
return "black"
},
color: "#fff",
"line-height": 0
}
}
let arr = [];
for (let i = 1; i < 13; i++) {
arr.push(".col-"+ i);
css[".col-"+ i] = {
"width": ((i/12) * 100).toString().slice(0,7) + "%"
}
}
css[arr.toString()] = {
"-ms-flex": "none",
flex: "none"
}
module.exports = css;
will produce
body {
background: black;
color: #fff;
line-height: 0
}
.col-1 {
width: 8.33333%
}
.col-2 {
width: 16.6666%
}
.col-3 {
width: 25%
}
.col-4 {
width: 33.3333%
}
.col-5 {
width: 41.6666%
}
.col-6 {
width: 50%
}
.col-7 {
width: 58.3333%
}
.col-8 {
width: 66.6666%
}
.col-9 {
width: 75%
}
.col-10 {
width: 83.3333%
}
.col-11 {
width: 91.6666%
}
.col-12 {
width: 100%
}
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
-ms-flex: none;
flex: none
}
Index
Globals
the globals object is where you keep an object congaing variables that are available
globally throughout css-node
- the g character is reserved for calling globals
- includes files, helpers and mixins have access to globals
- the globals file can be in the format of either
.js or .json
- the globals file path can be edited at
config.globals
- you can require and use external modules from within your globals file
module.exports = {
primary: "#333",
font_family: "-apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
extend: require('some/extra/globals')
}
let css = {
"body": {
"color": "#3b4351",
"background": g.primary,
"font-family": g.font_family,
}
}
module.exports = css;
will produce
body {
color: #3b4351;
background: #333;
font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif
}
Index
Mixins
- the m character is reserved for calling mixins
- mixins can be called from within includes files
- mixins can called from within mixins
- mixins have access to helpers and globals (h,g)
- the mixins file path can be edited at
config.mixins
- set
config.mixins to false to disable a mixins file
- set
config.mixins to a require /file/path relative to your cwd to enable your mixins
- you can require and use external modules from within your mixins file
- you can require and use other mixin files from within your mixins file
module.exports = {
text_size: function(obj, x){
return Object.assign(obj, {
"-webkit-text-size-adjust": x +"%",
"-ms-text-size-adjust": x +"%"
})
}
}
let css = {
html: m.text_size({"font-family": "sans-serif"}, 100)
}
module.exports = css;
will produce
html {
font-family:sans-serif;
-ms-text-size-adjust:100%;
-webkit-text-size-adjust:100%
}
Index
Helpers
- the h character is reserved for calling helpers
- css-node has a built in list of helpers that is easily extendable.
- helpers can be called from within includes files and mixins
- helpers have access to globals (g)
- the helpers extend file path can be edited/disabled at
config.helpers
- set
config.helpers to false to disable a custom helpers file
- set
config.helpers to a require /file/path relative to your cwd to enable your custom helpers
- you can require and use external modules from within your custom helpers file
- you can require and use extra helper files from within your custom helpers file
- you can replace any existing css-node base helper from within your custom helpers file
extra helpers can be added to the config.helpers file like so
module.exports = {
rgb2hex(rgb) {
let sep = rgb.indexOf(",") > -1 ? "," : " ";
rgb = rgb.substr(4).split(")")[0].split(sep);
let rh = (+rgb[0]).toString(16),
gh = (+rgb[1]).toString(16),
bh = (+rgb[2]).toString(16);
if (rh.length == 1){
rh = "0" + rh;
}
if (gh.length == 1){
gh = "0" + gh;
}
if (bh.length == 1){
bh = "0" + bh;
}
return "#" + rh + gh + bh;
}
}
let css = {
body: {
color: h.rgb2hex("rgb(255, 255, 255)"),
background: h.rgba2hex("rgba(103, 58, 183, 0.91)")
}
}
module.exports = css;
will produce
body: {
color: #ffffff;
background: #673ab7e8
}
css-node helpers
calc
body: {
"height": h.calc("2 * 6", "px"),
"height": h.calc("6 / 2", "px")
"height": h.calc("6 - 2", "em")
"height": h.calc("6 + 2", "rem")
}
add
body: {
"height": h.add(2, 4, "px")
}
sub
body: {
"height": h.sub(4, 2, "px")
}
mul
body: {
"height": h.mul(4, 2, "em")
}
div
body: {
"height": h.div(4, 2, "em")
}
floor
body: {
"height": h.floor(1.6, "em")
}
ceil
body: {
"height": h.ceil(.95, "em")
}
abs
body: {
"height": h.abs(-5, "em")
}
round
body: {
"height": h.round(1.6, "em")
}
percent
body: {
"height": h.percent(10,200)
}
inRange
h.inRange(3, 2, 4);
h.inRange(30, 2, 4);
h.inRange(-3, -2, -6);
path.base
h.path.base("path/to/img.png")
h.path.base("path/to/img.png", ".png")
path.dir
h.path.base("path/to/img.png")
path.ext
h.path.ext("path/to/img.png")
path.join
h.path.join("/foo", "bar", "baz/asdf", "quux", "..");
path.norm
h.path.norm("/foo/bar//baz/asdf/quux/..");
quote
h.quote("quote");
unquote
h.unquote("'unquote'");
upper
h.upper('zzz');
upperFirst
h.upperFirst('zzz');
lower
h.lower('ZZZ');
lowerFirst
h.lowerFirst('ZZZ');
pre
h.pre('prefix', '_');
suf
h.suf('suffix', '_');
starts
h.starts('abc', 'b', 1)
h.starts('abc', 'b', 2)
snake
h.snake('snake case');
unsnake
h.unsnake('un_snake_case');
camel
h.camel('camel case');
uncamel
h.uncamel('unCamelCase');
kebab
h.kebab('kebab case');
unkebab
h.unkebab('un-kebab-case');
is.string
h.is.string('string');
is.even
h.is.even(4);
h.is.even(3);
is.odd
h.is.odd(3);
h.is.odd(4);
is.number
h.is.number(3);
h.is.number('string');
is.lt
h.is.lt(3, 4);
h.is.lt(4,3);
is.lte
h.is.lte(4, 4);
h.is.lte(4,3);
is.eq
h.is.eq(3, 4);
h.is.eq(4,4);
h.is.eq("s3", "s4");
h.is.eq("s4","s4");
is.gt
h.is.gt(3, 4);
h.is.gt(4,3);
is.gte
h.is.gte(4, 4);
h.is.gte(4,3);
enc.base64
h.enc.base64('test')
enc.hex
h.enc.hex('test')
enc.URI
h.enc.URI('[]<>')
enc.URIC
h.enc.URIC('https://test.com/')
js
h.js({test: 'ok'});
h.js({test: 'ok'}, 0, 2);
jp
h.jp('{"test": "ok"}');
vendor
".example": vendor({
"height": h.div(4, 2, "em")
}, "box-shadow", "0 0 4px black", ["webkit"])
rgb2hex
"body": {
"background": h.rgb2hex("rgb(255, 255, 255)")
}
rgba2hex
"body": {
"background": h.rgba2hex("rgba(103, 58, 183, 0.91)")
}
hex2rgb
"body": {
"background": h.hex2rgb("#ffffff")
}
hex2rgba
"body": {
"background": h.hex2rgba("#673ab7e8")
}
keys
h.keys({
key1: '',
key2: '',
key3: ''
})
vals
h.vals({
key1: 'val1',
key2: 'val2',
key3: 'val3'
})
assign
let obj1 = {
key1: 'val1',
key2: 'val2',
key3: 'val3'
},
obj2 = {
key4: 'val4',
key5: 'val5',
key6: 'val6'
}
h.assign(obj1, obj2);
entries
h.entries({
key4: 'val4',
key5: 'val5',
key6: 'val6'
});
Index