A Light–weight CSS Preprocessor.
- Use a Direct Download:
<script src=stylis.js></script>
- Use a CDN:
<script src=unpkg.com/stylis></script>
- Use NPM:
npm install stylis --save
- nesting
a { &:hover {} }
- selector namespacing
- vendor prefixing (flex-box, etc...)
- minification
- esm module compatible
- tree-shaking-able
const declaration = {
value: 'color:red;',
type: 'decl',
props: 'color',
children: 'red',
line: 1, column: 1
}
const comment = {
value: '/*@noflip*/',
type: 'comm',
props: '/',
children: '@noflip',
line: 1, column: 1
}
const ruleset = {
value: 'h1,h2',
type: 'rule',
props: ['h1', 'h2'],
children: [/* ... */],
line: 1, column: 1
}
const atruleset = {
value: '@media (max-width:100), (min-width:100)',
type: '@media',
props: ['(max-width:100)', '(min-width:100)'],
children: [/* ... */],
line: 1, column: 1
}
import {compile, serialize, stringify} from 'stylis'
serialize(compile(`h1{all:unset}`), stringify)
compile('h1{all:unset}') === [{value: 'h1', type: 'rule', props: ['h1'], children: [/* ... */]}]
compile('--foo:unset;') === [{value: '--foo:unset;', type: 'decl', props: '--foo', children: 'unset'}]
tokenize('h1 h2 h3 [h4 h5] fn(args) "a b c"') === ['h1', 'h2', 'h3', '[h4 h5]', 'fn', '(args)', '"a b c"']
serialize(compile('h1{all:unset}'), stringify)
The middleware helper is a convinent helper utility, that for all intensive purposes you can do without if you intend to implement your own traversal logic. The stringify
middleware is one such middleware that can be used in conjunction with it.
Elements passed to middlewares have a root
property that is the immediate root/parent of the current element in the compiled output, so it references the parent in the already expanded CSS-like structure. Elements have also parent
property that is the immediate parent of the current element from the input structure (structure representing the input string).
serialize(compile('h1{all:unset}'), middleware([(element, index, children) => {
assert(children === element.root.children && children[index] === element.children)
}, stringify])) === 'h1{all:unset;}'
The abstract syntax tree also includes an additional return
property for more niche uses.
serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
if (element.type === 'decl' && element.props === 'all' && element.children === 'unset')
element.return = 'color:red;' + element.value
}, stringify])) === 'h1{color:red;all:unset;}'
serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
if (element.type === 'rule' && element.props.indexOf('h1') > -1)
return serialize([{...element, props: ['h2', 'h3']}], callback)
}, stringify])) === 'h2,h3{all:unset;}h1{all:unset;}'
serialize(compile('h1{all:unset}'), middleware([stringify, (element, index, children) => {
assert(element.return === 'h1{all:unset;}')
}])) === 'h1{all:unset;color:red;}'
The middlewares in src/Middleware.js dive into tangible examples of how you might implement a middleware, alternatively you could also create your own middleware system as compile
returns all the nessessary structure to fork from.
Stylis is at-least 2X faster than its predecesor.
Stylis is MIT licensed.