Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

j2c

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

j2c

A JavaScript object to CSS compiler.

  • 0.1.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
76
increased by11.76%
Maintainers
1
Weekly downloads
 
Created
Source

j2c

A small JavaScript object to CSS compiler. ~820 bytes mingzipped.

Think SASS, but in JSONish syntax.

Inspired by restlye.js and JSS, but smaller :-).


Table of Contents

TOC generated with DocToc


Why?

  • Send small, compact, SASS-like data down the line
  • Simplify your asset pipeline
  • Use the full power of JavaScript to create mixins, variables and macros
  • Stop worrying about vendor prefixes
  • Good fit for virtual DOM frameworks like React or Mithril
  • I like writing compilers :-).

Usage

For building a style sheet

j2c.vendors = [] // for the sake of this demo
                 // defaults to ["o", "ms", "moz", "webkit"].

r = j2c.sheet("ul.my_root_class")

r.add({
    "@media condition": {
        color: "red"
    },
    // properties for the main ul.my_root_class elements
    font: { 
        size: "2em",
        family: "sans-serif"
    },
    // underscores in property names are converted to dashes.
    background_color: "#44f", 

    // sub-selector for children element, notice the mandatory initial space
    // signifying a child element.
    " li": { 
        padding:{
            left: "5px"
            top: "10px"
        } 
    }
})

console.log(r.toString())

Output:

@media condition{
  ul.my_root_class {
    color:red;
  }
}
ul.my_root_class  li{
  padding-left:5px;
  padding-top:10px;
}
ul.my_root_class {
  font-size:2em;
  font-family:sans-serif;
  background-color:#44f;
}
-vendor-prefixes

If you don't truncate the vendors list as I did in the example above, you'll get each property prefixed for each vendor.

Most of the resulting combinations don't make any sense (-moz-color FTW), and they are simply ignored by browsers. That's the price to pay for the small code size.

root selector

If no root selector is provided, J2C creates one (a unique class).

r = j2c.sheet()
r.prefix // --> ".j2c_$token_$counter" where `$token` is unique per
         //     j2c instance, and `$counter` is incremented to 
         //     ensure that these classes are unique.
Telling selectors and properties apart

j2c considers that object keys matching /^[-_0-9A-Za-z]+$/ as properties, and everything else as (sub-)selectors.

Selectors are concatenated as is, while properties are concatenated with hyphens. {" ul": {" li": {padding: {left:10}}}} becomes ul li{padding-left:10px;}. {" p":{".foo":{color:"red"}}}, is translated to p.foo:{color:red;}.

Overloading properties
r = j2c.sheet("ul.my_root_class")

r.add({
    "font-size": ["2em", "2rem"]
})

console.log(r.toString())

becomes

.foo {
  font-size:2em;
  font-size:2rem;
}

Alternatively

r = j2c.sheet("ul.my_root_class")

r.add([
    {
        "font-size": "2em"
    },
    {
        "font-size": "2rem"
    }
])

console.log(r.toString())

becomes

ul.my_root_class {
  font-size:2em;
}
ul.my_root_class {
  font-size:2rem;
}
At-rules

Most At-rules are handled out of the box by sheet.add(). However, @font-face and @keyframes have are not covered and they are implemented respectively by sheet.font(definitions) and sheet.keyframes(name, definitions). The latter automatically generates browser-specific @-vendor-keyframes blocks.

Combining multiple selectors

Here's a excerpt from the j2c port of the PocketGrid.

j2c.sheet("").add({
  ".block,.blockgroup":{
    ",:before,:after":{          // Notice the initial coma.
      "box-sizing":"border-box"
    }
  }
}

Nesting ",:before,:after" inside the ".block,.blockgroup" block combines [".block", ".blockgroup"] with ["", ":before", ":after"], giving

.block,.block:before,.block:after,.blockgroup,.blockgroup:before,.blockgroup:after{
    box-sizing:border-box
}

Mathy folks call this as a Cartesian product.

CSS Hacks

Since sheet.add only accepts property names that match /^[-_0-9A-Za-z]+$/, it is not possible to express CSS hacks using objects. You can, however, work around the issue by using arrays and strings instead.

Here's another modified excerpt from the PocketGrid port:

j2c.sheet("").add({
  ".blockgroup": [
    "*zoom: 1; /* hack */",
    {
      "list-style-type":"none",
      padding:0,
      margin:0
    }
  ]
})

Array elements are inserted in sequence, and string literals are treated as a list of properties, and inserted as is.

Result:

.blockgroup{
*zoom: 1; /* hack */
}
.blockgroup{
  list-style-type:none;
  padding:0;
  margin:0;
}

For building inline styles

console.log(j2c.inline({
    float:"left";
}));

... outputs ...

-o-float:left;
-ms-float:left;
-moz-float:left;
-webkit-float:left;
float:left;

API Reference

j2c object

  • j2c.inline(props:(Object|Array|String)) : String: returns a declaration list suitable for inline styles
  • j2c.sheet([root:String]) : Sheet: Creates a Sheet object.
  • j2c.vendors = ["o", "ms", "moz", "webkit"] (r/w): list of vendor prefixes.

Sheet methods

  • sheet.add(statements:(Object|Array|String)) : Sheet: add a series of statements to the style sheet. Returns the Sheet for chaining.
  • sheet.font(definitions:(Object|Array|String)) : Sheet: creates a @font-face block. Returns the Sheet for chaining.
  • sheet.keyframes(name:String, statements:(Object|Array|String)) : Sheet: creates a @keyframes block. Returns the Sheet for chaining.
  • sheet.toString() : String: the stylesheet in string form.

Limitations

Selectors and properties order

j2c relies on JS objects to define selectors and properties. As a consequence, the source order cannot be guaranteed to be respected in the output.

j2c(".hello").add({
  foo:"bar",
  baz:"qux"
}).toString()

This may produce either .hello{foo:bar;baz:qux;} or .hello{baz:qux;foo:bar;}.

If you need some elements to happen in order, use an array of objects.

j2c(".hello").add([
  {foo:"bar"},
  {baz:"qux"}
]).toString()

This will always yield .hello{foo:bar;}.hello{baz:qux;}.

No input validation

j2c knows the bare minimum to output a valid stylesheet when provided with valid input. It will hapily accept invalid selectors, properties and values, and could in that case produce a broken stylesheet.

I may get around and write a validator companion, but I'm not there yet :-).

License: MIT

Keywords

FAQs

Package last updated on 20 Apr 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc