Today, we're going to talk about one unique Javascript library, that is JSS.
What is it?
JSS, or CSS-in-JS, is a Javascript library that allows you to write CSS styles through Javascript objects. With JSS, you wouldn't write any .css file, rather you would write all styles in your Javascript files.
How to use it?
We'll use Webpack to demonstrate the use of JSS. We'll make a simple web page that consists of 2 modules: Card and Button module.
Here are the steps:
- Install
webpackandwebpack-cliin your project.npm install webpack webpack-cli --save-dev - Install
jssandjss-preset-defaultin your project.npm install jss jss-preset-default --save-dev - Here's the project structure. Notice that there are no CSS files anywhere. Weird, right?
. ├── dist │ ├── index.html ├── src │ ├── button │ | ├── index.js │ ├── card │ | ├── index.js │ ├── index.js ├── package.json └── webpack.config.jsdist/index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Example JSS</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div id="root"></div> <script src="bundle.js"></script> </body> </html>src/button/index.js
This is where we defineButtonmodule. Notice that all styles are defined in thestylevariable.import { create } from 'jss'; import preset from 'jss-preset-default'; // create JSS instance const jss = create(); // load default plugins jss.setup(preset()); // define styles const style = { container: { border: '1px solid gray', padding: '10px', background: 'none', cursor: 'pointer', }, '@media (min-width: 1024px)': { container: { padding: '20px', } } }; // create style sheet const { classes } = jss.createStyleSheet(style).attach(); export function Button(text) { var btn = document.createElement('button'); btn.className = classes.container; // use style sheet btn.textContent = text; return btn; }src/card/index.js
Similar to the previous file, this is where theCardmodule is defined. Notice that both modules use a CSS class namedcontainer. This is totally fine and won't cause any conflict, as JSS will rename all CSS class names later.import {create} from 'jss'; import preset from 'jss-preset-default'; const jss = create(); jss.setup(preset()); const style = { container: { border: '1px solid black', padding: '20px', }, }; const {classes} = jss.createStyleSheet(style).attach(); export function Card() { var div = document.createElement('div'); div.className = classes.container; return div; }src/index.js
import { Button } from './button/index.js'; import { Card } from './card/index.js'; function app() { var el = Card(); el.appendChild(Button('button 1')); return el; } var root = document.getElementById('root'); root.appendChild(app());webpack.config.js
// webpack.config.js const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, watch: true, }; - Run Webpack command:
npx webpackto bundle all files into dist/bundle.js. - Open dist/index.html file and you'll get this result:

That's the basic of JSS!
Now, we'll delve into the the most important part of JSS, which is its plugins.
In the example above, we use the default plugins by using jss-preset-default. By default, jss-preset-default will load these following plugins:
jss-camel-case
This plugin enables you to use camelCase when writing CSS properties. For example:
// before const style = { container: { 'border-radius': '5px' } }; // after const style = { container: { borderRadius: '5px' } };jss-compose
This plugin enables you to compose CSS classes with other classes. For example:
// before const style = { clickable: { cursor: 'pointer', }, container: { borderRadius: '5px' } }; btn.className = classes.container+' '+classes.clickable; // after const style = { clickable: { cursor: 'pointer', }, container: { composes: ['$clickable'], borderRadius: '5px' } }; btn.className = classes.container;jss-default-unit
This plugin enables you to omit the units when writing CSS property values. For example:
// before const style = { container: { borderRadius: '5px' } }; // after const style = { container: { borderRadius: 5 } };jss-expand
This plugin offers a better syntax for writing CSS properties. For example:
// before const style = { container: { borderRadius: '5px', boxShadow: '1px 1px 5px 5px black' } }; // after const style = { container: { borderRadius: '5px', boxShadow: { x: 1, y: 1, blur: 1, spread: 1, color: 'black' } } };jss-extend
This plugin enables you to extend CSS classes with other classes. For example:
// before const style = { container: { borderRadius: '5px', }, blueContainer: { borderRadius: '5px', background: 'blue' } }; // after const style = { container: { borderRadius: '5px', }, blueContainer: { extend: 'container', background: 'blue' } };jss-global
This plugin enables you to define global CSS class in JSS (although this is not recommended). For example:
const style = { '@global': { body: { background: 'green' } }, container: { borderRadius: '5px', boxShadow: '1px 1px 5px 5px black' } };jss-nested
This plugin enables nesting in your CSS classes. For example:
const style = { container: { borderRadius: '5px', '&:hover': { background: 'blue' } } };jss-props-sort
This plugin automatically reorders your CSS properties so that they don't override each other. For example:
const style = { container: { borderLeft: '1px solid green', border: '2px solid black', } };This will be compiled to this CSS:
.c001 { border: 2px solid black; border-left: 1px solid green; }jss-template
This plugin enables the use of string template for CSS property values. For example:
// before const style = { container: { borderLeft: '1px solid green', border: '2px solid black', } }; // after const style = { container: ` border-left: 1px solid green; border: 2px solid black; ` };jss-vendor-prefixer
This plugin automatically handles vendor prefixing for you. For example:
This will be compiled to:const style = { container: { transform: 'translateX(20px)' } };
.c001 { transform: -webkit-translateX(20px); }
That's all of it!