Neoclassical Philosophic Musings

    css-node

    1.0.1 • Public • Published

    css-node

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

    cd-img dep-img sz-img

    NPM Version lic-img

    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')
     
    // build initial project setup ~ should only be called once
    init()
     
     
     
    const { build, watch } = require('css-node')
     
    // watch files listed at config.watch.files
    watch(function(file, stats){
      console.log(file); // log change detected file path
      console.log(stats); // log file stats
     
      // watch files listed at config.watch.files
      build(function(err, css){
        if(err){return console.log(err)}
        console.log(css) // compiled 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:

    // ./ncss.json
    {
      "dest": "/ncss/dist/app.min.css", //
      "globals": "/ncss/globals", // false || globals require path relative to cwd
      "mixins": "/ncss/mixins", // false || mixins require path relative to cwd
      "helpers": "/ncss/helpers", // false || helpers require path relative to cwd
      "sort_order": false, // sort css entries
      "sort_properties": false, // sort css entries properties
      "write_file": false, // callback css only if false
      "verbose": false, // print result to console
      "imports": [ // imports prepended to css file and in order of output
        "imported.css"
      ],
      "includes": [ // css imports path relative to cwd and in order of output
        "/ncss/includes/index.js"
      ],
      "watch": {
        "delay": 0, // watch delay response in ms
        "interval": 5007, // watch interval
        "files": [ // files to watch
          "/ncss/includes/index.js"
        ]
      }
    }

    js example:

    // ./ncss.js
    const config = {
      "dest": "/ncss/dist/app.min.css", // build file
      "globals": "/ncss/globals", // false || globals require path relative to cwd
      "mixins": "/ncss/mixins", // false || mixins require path relative to cwd
      "helpers": "/ncss/helpers", // false || helpers require path relative to cwd
      "sort_order": false, // sort css entries
      "sort_properties": false, // sort css entries properties
      "write_file": false, // callback css only if false
      "verbose": false, // print result to console
      "imports": [ // imports prepended to css file and in order of output
        "imported.css"
      ],
      "includes": [ // css imports path relative to cwd and in order of output
        "/ncss/includes/index.js"
      ],
      "watch": {
        "delay": 0, // watch delay response in ms
        "interval": 5007, // watch interval
        "files": [ // files to watch
          "/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.
    /* imports:["example.css","example2.css"] */
     
    @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

    // include ~ "/ncss/includes/index.js"
     
    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
    // /ncss/globals/index.js
     
    module.exports = {
      primary: "#333",
      font_family: "-apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
      extend: require('some/extra/globals')
    }
    // include ~ /ncss/includes/index.js
     
    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-systemsystem-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
    // /ncss/mixins/index.js
     
    module.exports = {
      text_size: function(obj, x){
        return Object.assign(obj, {
          "-webkit-text-size-adjust": x +"%",
          "-ms-text-size-adjust": x +"%"
        })
      }
    }
    // include ~ /ncss/includes/index.js
     
    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

    // /ncss/helpers/index.js
     
    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;
      }
    }
    // include ~ base.js
     
    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

    // calculate
    body: {
      "height": h.calc("2 * 6", "px"), // 12px
      "height": h.calc("6 / 2", "px") // 3px
      "height": h.calc("6 - 2", "em") // 4em
      "height": h.calc("6 + 2", "rem") //8rem
    }
     

    add

    // plus
    body: {
      "height": h.add(2, 4, "px") // 6px
    }
     

    sub

    // subtract
    body: {
      "height": h.sub(4, 2, "px") // 2px
    }
     

    mul

    // multiply
    body: {
      "height": h.mul(4, 2, "em") // 8em
    }
     

    div

    // divide
    body: {
      "height": h.div(4, 2, "em") // 2em
    }
     

    floor

    // Math.floor
    body: {
      "height": h.floor(1.6, "em") // 1em
    }
     

    ceil

    // Math.ceil
    body: {
      "height": h.ceil(.95, "em") // 1em
    }
     

    abs

    // Math.abs
    body: {
      "height": h.abs(-5, "em") // 5em
    }
     

    round

    // Math.round
    body: {
      "height": h.round(1.6, "em") // 2em
    }
     

    percent

    // return percentage
    body: {
      "height": h.percent(10,200) // 5%
    }
     

    inRange

     
    h.inRange(3, 2, 4); // true
     
    h.inRange(30, 2, 4); // false
     
    h.inRange(-3, -2, -6); // true
     

    path.base

     
    h.path.base("path/to/img.png") // 'img.png'
     
    h.path.base("path/to/img.png", ".png") // 'img'
     

    path.dir

     
    h.path.base("path/to/img.png") // 'path/to'
     

    path.ext

     
    h.path.ext("path/to/img.png") // .'png'
     

    path.join

     
    h.path.join("/foo", "bar", "baz/asdf", "quux", ".."); // '/foo/bar/baz/asdf'
     

    path.norm

     
    h.path.norm("/foo/bar//baz/asdf/quux/.."); // '/foo/bar/baz/asdf'
     

    quote

    h.quote("quote"); // 'quote'

    unquote

    h.unquote("'unquote'"); // unquote

    upper

     
    h.upper('zzz'); // ZZZ
     

    upperFirst

     
    h.upperFirst('zzz'); // Zzz
     

    lower

     
    h.lower('ZZZ'); // zzz
     

    lowerFirst

     
    h.lowerFirst('ZZZ'); // zZZ
     

    pre

    // add prefix
    h.pre('prefix', '_'); // _prefix
     

    suf

    // add duffix
    h.suf('suffix', '_'); // suffix_
     

    starts

    // starts with
    h.starts('abc', 'b', 1) //true
    h.starts('abc', 'b', 2) //false
     

    snake

     
    h.snake('snake case'); // snake_case
     

    unsnake

     
    h.unsnake('un_snake_case'); // un snake case
     

    camel

     
    h.camel('camel case'); // camelCase
     

    uncamel

     
    h.uncamel('unCamelCase'); // un camel case
     

    kebab

     
    h.kebab('kebab case'); // kebab-case
     

    unkebab

     
    h.unkebab('un-kebab-case'); // un kebab case
     

    is.string

     
    h.is.string('string'); // true
     

    is.even

     
    h.is.even(4); // true
     
    h.is.even(3); // false
     

    is.odd

     
    h.is.odd(3); // true
     
    h.is.odd(4); // false
     

    is.number

     
    h.is.number(3); // true
     
    h.is.number('string'); // false
     

    is.lt

    // less than
    h.is.lt(3, 4); // true
     
    h.is.lt(4,3); // false
     

    is.lte

    // less than or equal
    h.is.lte(4, 4); // true
     
    h.is.lte(4,3); // false
     

    is.eq

    // greater than
    h.is.eq(3, 4); // false
     
    h.is.eq(4,4); // true
     
    h.is.eq("s3", "s4"); // false
     
    h.is.eq("s4","s4"); // true
     

    is.gt

    // greater than
    h.is.gt(3, 4); // false
     
    h.is.gt(4,3); // true
     

    is.gte

    // greater than or equal
    h.is.gte(4, 4); // false
     
    h.is.gte(4,3); // true
     

    enc.base64

    // base64 encode utf8 string
    h.enc.base64('test') // dGVzdA==
     

    enc.hex

    // hex encode utf8 string
    h.enc.hex('test') // 74657374
     

    enc.URI

    // URI encode utf8 string
    h.enc.URI('[]<>') // %5B%5D%3C%3E
     

    enc.URIC

    //  encode URI Component utf8 string
    h.enc.URIC('https://test.com/') // https%3A%2F%2Ftest.com%2F
     

    js

    //  JSON.stringify
     
    h.js({test: 'ok'}); // '{"test":"ok"}'
     
    h.js({test: 'ok'}, 0, 2);
    /*
    {
      "test": "ok"
    }
    */
     

    jp

    //  JSON.parse
    h.jp('{"test": "ok"}'); // {test:'ok'}
     

    vendor

     
    ".example": vendor({
      "height": h.div(4, 2, "em") // 2em
    }, "box-shadow", "0 0 4px black", ["webkit"])
     
    /*
    .example {
      height: 2em;
      box-shadow: 0 0 4px black;
      -webkit-box-shadow: 0 0 4px black
    }
     
    */

    rgb2hex

     
    "body": {
      "background": h.rgb2hex("rgb(255, 255, 255)") // #ffffff
    }
     

    rgba2hex

     
    "body": {
      "background": h.rgba2hex("rgba(103, 58, 183, 0.91)") // #673ab7e8
    }
     

    hex2rgb

     
    "body": {
      "background": h.hex2rgb("#ffffff") // rgb(255, 255, 255)
    }
     

    hex2rgba

     
    "body": {
      "background": h.hex2rgba("#673ab7e8") // rgba(103, 58, 183, 0.91)
    }
     

    keys

     
    h.keys({
      key1: '',
      key2: '',
      key3: ''
    }) // ["key1","key2":"key3"]
     

    vals

     
    h.vals({
      key1: 'val1',
      key2: 'val2',
      key3: 'val3'
    }) // ["val1","val2":"val3"]
     

    assign

    let obj1 = {
      key1: 'val1',
      key2: 'val2',
      key3: 'val3'
    },
    obj2 = {
      key4: 'val4',
      key5: 'val5',
      key6: 'val6'
    }
     
    h.assign(obj1, obj2);
     
    /*
    {
      key1: 'val1',
      key2: 'val2',
      key3: 'val3',
      key4: 'val4',
      key5: 'val5',
      key6: 'val6'
    }
    */
     

    entries

     
    h.entries({
      key4: 'val4',
      key5: 'val5',
      key6: 'val6'
    });
     
    // [ [ 'key4', 'val4' ], [ 'key5', 'val5' ], [ 'key6', 'val6' ] ]
     

    Index

    Install

    npm i css-node

    DownloadsWeekly Downloads

    4

    Version

    1.0.1

    License

    MIT

    Unpacked Size

    32.9 kB

    Total Files

    10

    Last publish

    Collaborators

    • angeal185