npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

css-node

v1.0.1

Published

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

Downloads

8

Readme

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-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
// /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