JSPM

  • Created
  • Published
  • Downloads 2319350
  • Score
    100M100P100Q182260F

Dynamic stylesheets for web components.

Package Exports

  • jss
  • jss/lib

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (jss) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Dynamic stylesheets for web components.

Why do we need transpilers like sass or stylus when we can use javascript to do the same and much more?

By leveraging namespaces we can solve the cascading problem better than bem and make our components truly reusable and composable.

Access css declarations and values from js without DOM round trip.

Smaller footprint because of code reuse and no vendor specific declarations

Take a look at examples directory.

Built in preprocessors

Jss styles are just plain javascript objects. They map 1:1 to css rules, except of those modified by preprocessors.

Nested Rules

Put an & before a selector within a rule and it will be replaced by the parent selector and extracted to a separate rule.

{
    '.container': {
        padding: '20px',
        // Will result in .container.clear
        '&.clear': {
            clear: 'both'
        },
        // Will result in .container .button
        '& .button': {
            background: 'red'
        },
        '&.selected, &.active': {
            border: '1px solid red'
        }
    }
}
.container {
    padding: 20px;
}
.container.clear {
    clear: both;
}
.container .button {
    background: red;
}
.container.selected, .container.active {
    border: 1px solid red;
}

Inheritance

Inherit a rule(s) by using extend keyword. This makes it easy to reuse code. See example.

var rules = {}

var button1 = {
    padding: '20px',
    background: 'blue'
}

rules['.button-1'] = button1

rules['.button-2'] = {
    extend: button1, // can be an array of styles
    padding: '30px'
}
.button-1 {
    padding: 20px;
    background: blue;
}

.button-2 {
    padding: 30px;
    background: blue;
}

Vendor prefixes

Vendor prefixes are handled automatically using a smart check which results are cached. See example.

{
    '.container': {
        transform: 'translateX(100px)'
    }
}
.container {
    transform: -webkit-translateX(100px);
}

API

Access the jss namespace

// Pure js
var jss = window.jss

// Commonjs
var jss = require('jss')

Create stylesheet

jss.createStylesheet([rules], [named], [attributes])

  • rules is an object, where keys are selectors if named is not true
  • named rules keys are not used as selectors, but as names, will cause auto generated class names and selectors. It will also make class names accessible via stylesheet.classes.
  • attributes allows to set any attributes on style element.
var stylesheet = jss.createStylesheet({
    '.selector': {
        width: '100px'
    }
}, {media: 'print'}).attach()
<style media="print">
    .selector {
        width: 100px;
    }
</style>

Create a stylesheet with namespaced rules.

var stylesheet = jss.createStylesheet({
    myButton: {
        width: '100px',
        height: '100px'
    }
}, true).attach()

console.log(stylesheet.classes.myButton) // .jss-0
<style>
    .jss-0 {
        width: 100px;
        height: 100px;
    }
</style>

Attach stylesheet

stylesheet.attach()

Insert stylesheet into render tree.

stylesheet.attach()

Detach stylesheet

stylesheet.detach()

Remove stylesheet from render tree to increase runtime performance.

stylesheet.detach()

Add a rule

stylesheet.addRule([selector], rule)

You might want to add rules dynamically.

var button = stylesheet.addRule('.my-button', {
    padding: '20px',
    background: 'blue'
})

Generated namespace.

In case you have an element reference or you create elements in javascript you might want to write styles and attach them later to the element using a generated class name.

var button = stylesheet.addRule({
    padding: '20px',
    background: 'blue'
})

document.body.innerHTML = '<button class="' + button.className + '">Button</button>'

Get a rule

stylesheet.getRule(selector)

// Using selector
var rule = stylesheet.getRule('.my-button')

// Using name, if named rule was added.
var rule = stylesheet.getRule('myButton')

Add a rules

stylesheet.addRules(rules)

Add a list of rules.

stylesheet.addRules({
    '.my-button': {
        float: 'left',
    },
    '.something': {
        display: 'none'
    }
})

Create a rule without a stylesheet.

jss.createRule([selector], rule)

var rule = jss.createRule({
    padding: '20px',
    background: 'blue'
})

// Apply styles directly using jquery.
$('.container').css(rule.style)

Install

npm i jss

Convert CSS to JSS

# print help
jss
# convert css
jss source.css -p > source.jss

Benchmarks

To make some realistic assumptions about performance overhead, I have converted bootstraps css to jss. In bench/bootstrap folder you will find jss and css files. You need to try more than once to have some average value.

In my tests overhead is 10-15ms.

Run tests

Locally

npm i
open test/local.html

From github

Tests

License

MIT