Package Exports
- jss
- jss/lib
- jss/lib/Jss
- jss/lib/StyleSheet
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
Composable and reusable style sheets.

JSS is a very thin layer which compiles JSON structures to CSS.
Why? To solve composability and code reuse problems for components properly.
Take a look at "The important parts" and JSS is CSS.
By leveraging namespaces we can solve the cascading problem better than bem and make our components truly reusable and composable.
Why do we need transpilers like sass or stylus when we can use javascript to do the same and much more?
Access css declarations and values from js without DOM round trip.
Smaller footprint because of code reuse and no vendor specific declarations
Examples.
Working examples directory.
Example with extend, nesting, auto px.
export default {
carouselCaption: {
extend: something,
position: 'absolute',
zIndex: 10,
'&:hover': {
background: 'red'
}
},
hr: {
height: 1,
border: 0,
borderTop: '1px solid #eee'
}
}
Example with @media.
export default {
button: {
width: 100
},
'@media (min-width: 1024px)': {
button: {
width: 200
}
}
}
Plugins.
Jss styles are just plain javascript objects. They map 1:1 to css rules, except of those modified by plugins.
Some of those plugins:
- Nested rules is implemented through jss-nested plugin. Also you can do pseudo selectors like
:hover
via nested rules. - Use
extend
property to inherit from some plain rule object, via jss-extend - Vendor prefixes are automatically added through jss-vendor-prefixer plugin.
- You can use camel cased css property names through jss-camel-case plugin.
- Add 'px' automatically to non numeric values using jss-px
Order does matter! Here is the right one:
- jss-extend
- jss-nested
- jss-camel-case
- jss-px
- jss-vendor-prefixer
- jss-props-sort
Authoring plugins is easy.
Register plugin.
jss.use(fn)
Passed function will be invoked with Rule instance. Take a look at plugins like extend
, nested
or vendorPrefixer
.
jss.use(function(rule) {
// Your modifier.
})
Multiple declarations with identical property names.
I recommend to not to use this if you use jss on the client. Instead you should write a function, which makes a test for this feature support and generates just one final declaration.
In case you are using jss as a server side precompiler, you might want to have more than one property with identical name. This is not possible in js, but you can use an array.
export default {
container: {
background: [
'red',
'-moz-linear-gradient(left, red 0%, green 100%)',
'-webkit-linear-gradient(left, red 0%, green 100%)',
'-o-linear-gradient(left, red 0%, green 100%)',
'-ms-linear-gradient(left, red 0%, green 100%)',
'linear-gradient(to right, red 0%, green 100%)'
]
}
}
.jss-0-0 {
background: red;
background: -moz-linear-gradient(left, red 0%, green 100%);
background: -webkit-linear-gradient(left, red 0%, green 100%);
background: -o-linear-gradient(left, red 0%, green 100%);
background: -ms-linear-gradient(left, red 0%, green 100%);
background: linear-gradient(to right, red 0%, green 100%);
}
API
Access the jss namespace.
// Pure js
var jss = window.jss
// Commonjs
var jss = require('jss')
// ES6
import jss from 'jss'
Create an own instance of JSS.
Use an own instance if the component you build should be reusable within a different project with a probably different JSS setup.
jss.create()
// ES5
var jss = require('jss').create()
jss.use(somePlugin)
jss.createStyleSheet(...)
// ES6
import {create} from 'jss'
let jss = create()
jss.use(somePlugin)
jss.createStyleSheet(...)
Create style sheet with namespaces enabled.
Create a style sheet with namespaced rules.
jss.createStyleSheet([rules], [options])
Options:
media
style element attributetitle
style element attributetype
style element attributenamed
true by default - keys are names, selectors will be generated, if false - keys are global selectors.link
link jssRule
instances with DOMCSSRule
instances so that styles, can be modified dynamically, false by default because it has some performance cost.
// Namespaced style sheet with generated selectors.
let sheet = jss.createStyleSheet({
myButton: {
width: 100,
height: 100
}
}, {media: 'print'}).attach()
console.log(sheet.classes.myButton) // .jss-0-0
<style media="print">
.jss-0-0 {
width: 100px;
height: 100px;
}
</style>
Create regular style sheet with global selectors.
let sheet = jss.createStyleSheet({
'.something': {
width: 100,
height: 100
}
}, {named: false}).attach()
<style>
.something {
width: 100px;
height: 100px;
}
</style>
Attach style sheet.
sheet.attach()
Insert style sheet into the render tree. You need to call it in order to make your style sheet visible for the layout.
Detach style sheet.
sheet.detach()
Detaching unsused style sheets will speedup every DOM node insertion and manipulation as the browser will have to do less lookups for css rules potentially to be applied to the element.
Add a rule to an existing style sheet.
sheet.addRule([selector], rule)
Add a rule dynamically with a generated class name.
let rule = sheet.addRule({
padding: 20,
background: 'blue'
})
document.body.innerHTML = '<button class="' + rule.className + '">Button</button>'
Add a rule with global class name.
let rule = sheet.addRule('.my-button', {
padding: 20,
background: 'blue'
}, {named: false})
Get a rule.
sheet.getRule(name)
Access a rule within sheet by selector or name.
// Using name, if named rule was added.
let rule = sheet.getRule('myButton')
// Using selector
let rule = sheet.getRule('.my-button')
Add multiple rules.
sheet.addRules(rules)
In case you want to add rules to the sheet separately or even at runtime.
sheet.addRules({
myButton: {
float: 'left',
},
something: {
display: 'none'
}
})
Create a rule without a style sheet.
jss.createRule([selector], rule)
In order to apply styles directly to the element but still be able to use jss plugins.
let rule = jss.createRule({
padding: 20,
background: 'blue'
})
Apply a rule to an element inline.
rule.applyTo(element)
This is equivalent to element.style.background = 'blue'
except of that you could use a rule from sheet which is already defined and can apply plugins to it. Example.
jss.createRule({
background: 'blue'
}).applyTo(element)
Set or get a rule property dynamically.
rule.prop(name, [value])
When option link
is true, after stylesheet is attached, linker saves references to CSSRule
instances so that you are able to set rules properties at any time. Example.
let sheet = jss.createStyleSheet({
a: {
color: 'red'
}
}, {link: true})
// Get the color.
sheet.getRule('a').prop('color') // red
// Set the color.
sheet.getRule('a').prop('color', 'green')
Convert rule to a JSON.
rule.toJSON()
Returns JSON representation of a rule. Only regular rules are supported, no nested, conditionals, keyframes or array values.
Result of toJSON call can be used later to apply styles inline to the element.
Convert to CSS
sheet.toString()
If you want to get a pure CSS string from JSS for e.g. when preprocessing server side.
import jss from 'jss'
let sheet = jss.createStyleSheet({
myButton: {
float: 'left',
}
})
console.log(sheet.toString())
.jss-0-0 {
float: left;
}
Install
npm i jss
A command line interface for JSS is also available:
npm i jss-cli -g
For more information see CLI.
Benchmarks
How fast would bootstrap css lib render? 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.On my machine overhead is about 10-15ms.
Rendering jss vs. css (same styles) jsperf bench.
Run tests
Locally
npm i
open test/local.html
From github
License
MIT