Overview
- History
- Composition
- Code reuse
- Vendor prefixing
- CSS globals
- Sharing values
- Overhead
- More optimizations
Javascript Style Sheets
    <style type="text/javascript">
        tags.H1.color = "blue";
    </style>Cascades and Composition
Lets create a component "A" with a button.
    component-a button {
        background: red;
    }
Lets create a component "B" with a button.
    component-b button {
        color: green;
    }
Now lets compose them.
Lets use component B within component A.
    <component-a>
        <button>Button A</butotn>
        <component-b>
            <button>Button B</butotn>
        </component-b>
    </component-a>Is this what we
want to get?


2 problems
1. Cascading
Is only useful when you are never going to
compose components.
2. Global selectors
Is a bad practice and we all know why, right?
Lets rewrite it using JS
    // component-a.js
    module.exports = {
        button: {
            background: 'red'
        }
    }
    
    // component-b.js
    module.exports = {
        button: {
            color: 'green'
        }
    }
    
    // app.js
    var a = require('./component-a')
    var b = require('./component-b')
    jss.createStyleSheet(a, true).attach()
    jss.createStyleSheet(b, true).attach()
Both problems solved.
- We don't rely on cascading
- Selectors are generated and are unique
    <style>
        .jss-0 {
            background: red;
        }
    </style>
    
    <style>
        .jss-1 {
            color: green;
        }
    </style>
Code reuse in CSS
- Multiple classes on one element
- Global selectors
Code reuse in JSS
Is infinitely flexible.
- Truly reusable css components
- Save up to 30% in size
Inheritance
Done by "extend" plugin.
    // base-button.js
    module.exports = {
        color: 'red'
    }
    
    // styles.js
    var baseButton = require('./base-button')
    module.exports = {
        '.button': {
            extend: baseButton,
            float: 'left'
        }
    }
    
    // app.js
    var styles = require('./styles')
    jss.createStyleSheet(styles).attach()      
    <style>
        .button {
            color: red;
            float: left;
        }
    </style>Nesting
Done by "nested" plugin.
    // styles.js
    module.exports = {
        '.button': {
            float: 'left',
            '&:hover': {
                color: 'red'
            },
            '& .icon': {
                border: '1px solid red'
            }
        }
    }
    
    // app.js
    var styles = require('./styles')
    jss.createStyleSheet(styles).attach()  
    <style>
        .button {
            float: left;
        }
        .button:hover {
            color: red;
        }
        .button .icon {
            width: 20px;
            height: 20px
        }
    </style>Vendor prefixes
Done by "vendorPrefixer" plugin.
Added very efficiently at runtime.
    // styles.js
    module.exports = {
        '.button': {
            transform: 'translateX(100px)'
        }
    }
    
    // app.js
    var styles = require('./styles')
    jss.createStyleSheet(styles).attach()  
    <style>
        .button {
            -webkit-transform: translate(100px);
        }
    </style>Sharing values
Now it's really easy to reuse and access constants.
    // vars.js
    module.exports = {
        color: '#fff',
        height: 20
    }
    
    
    // styles.js
    var vars = require('./vars')
    module.exports = {
        button: {
            color: vars.color,
            height: vars.height + 'px'
        }
    }
    // app.js
    var vars = require('./vars')
    // Do something usefull    
    $('something').height(vars.height)
Direct injection
    // styles.js
    module.exports = {
        button: {
            padding: '20px',
            background: 'blue'
        }
    }
    
    // app.js
    var styles = require('./styles')
    var sheet = jss.createStyleSheet(styles, true)
    sheet.rules.button.applyTo($('button')[0])
    
Why share values?
- DOM round trip is expensive
- get initial value directly
- calculate relative values
- use values in different places e.g. inline
JS layout engines will love it!
Overhead?
bootstrap css (134kb) vs. bootstrap jss:
http://jsstyles.github.io/jss/bench/bootstrap/css.html
http://jsstyles.github.io/jss/bench/bootstrap/jss.html
Jss overall overhead ~10-15ms on desktop chrome.
More optimizations?
Critical path
You might want to convert critical path
jss to css and inline it.
    var ss = jss.createStyleSheet({
        'a': {
            color: 'red'
        }
    })
    console.log(ss.toString())
    
    
    // Output
    a {
        color: red;
    }
Unused CSS
- 
	Render jss styles only for components which are in the render tree. 
- 
	Remove jss styles when components are detached. 
JSS
By Oleg Isonen
JSS
Dynamic stylesheets for web components.
- 26,846
 
   
   
  