Gathering detailed insights and metrics for stylis
Gathering detailed insights and metrics for stylis
Gathering detailed insights and metrics for stylis
Gathering detailed insights and metrics for stylis
npm install stylis
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1,737 Stars
663 Commits
84 Forks
19 Watching
6 Branches
33 Contributors
Updated on 19 Nov 2024
Minified
Minified + Gzipped
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
-5.4%
2,802,163
Compared to previous day
Last week
1.8%
15,620,038
Compared to previous week
Last month
7.1%
66,286,230
Compared to previous month
Last year
42.4%
689,794,306
Compared to previous year
A Light–weight CSS Preprocessor.
<script src=stylis.js></script>
<script src=unpkg.com/stylis></script>
npm install stylis --save
a { &:hover {} }
1const declaration = { 2 value: 'color:red;', 3 type: 'decl', 4 props: 'color', 5 children: 'red', 6 line: 1, column: 1 7} 8 9const comment = { 10 value: '/*@noflip*/', 11 type: 'comm', 12 props: '/', 13 children: '@noflip', 14 line: 1, column: 1 15} 16 17const ruleset = { 18 value: 'h1,h2', 19 type: 'rule', 20 props: ['h1', 'h2'], 21 children: [/* ... */], 22 line: 1, column: 1 23} 24 25const atruleset = { 26 value: '@media (max-width:100), (min-width:100)', 27 type: '@media', 28 props: ['(max-width:100)', '(min-width:100)'], 29 children: [/* ... */], 30 line: 1, column: 1 31}
1import {compile, serialize, stringify} from 'stylis' 2 3serialize(compile(`h1{all:unset}`), stringify)
1compile('h1{all:unset}') === [{value: 'h1', type: 'rule', props: ['h1'], children: [/* ... */]}] 2compile('--foo:unset;') === [{value: '--foo:unset;', type: 'decl', props: '--foo', children: 'unset'}]
1tokenize('h1 h2 h3 [h4 h5] fn(args) "a b c"') === ['h1', 'h2', 'h3', '[h4 h5]', 'fn', '(args)', '"a b c"']
1serialize(compile('h1{all:unset}'), stringify)
1import {compile, serialize, stringify, middleware, prefixer } from 'stylis'; 2 3serialize(compile('div{display:flex;}'), middleware([prefixer, stringify]))
The middleware helper is a convenient helper utility, that for all intents and 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).
1serialize(compile('h1{all:unset}'), middleware([(element, index, children) => { 2 assert(children === element.root.children && children[index] === element.children) 3}, stringify])) === 'h1{all:unset;}'
The abstract syntax tree also includes an additional return
property for more niche uses.
1serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => { 2 if (element.type === 'decl' && element.props === 'all' && element.children === 'unset') 3 element.return = 'color:red;' + element.value 4}, stringify])) === 'h1{color:red;all:unset;}'
1serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => { 2 if (element.type === 'rule' && element.props.indexOf('h1') > -1) 3 return serialize([{...element, props: ['h2', 'h3']}], callback) 4}, stringify])) === 'h2,h3{all:unset;}h1{all:unset;}'
1serialize(compile('h1{all:unset}'), middleware([stringify, (element, index, children) => { 2 assert(element.return === 'h1{all:unset;}') 3}])) === '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.
CSS variables are supported but a note should be made about the exotic use of css variables. The css spec mentions the following
The allowed syntax for custom properties is extremely permissive. The
production matches any sequence of one or more tokens, so long as the sequence does not contain , , unmatched <)-token>, <]-token>, or <}-token>, or top-level tokens or tokens with a value of "!".
That is to say css variables according to the spec allows: --foo: if(x > 5) this.width = 10;
and while this value is obviously useless as a variable, and would be invalid in any normal property, it still might be read and acted on by JavaScript and this is supported by Stylis, however things become slightly undefined when we start to include the {
and }
productions in our use of exotic css variables.
For example consider the following: --foo: {};
While this is valid CSS and supported. It is unclear what should happen when the rule collides with the implicit block termination rule that allows i.e h1{color:red}
(notice the omitted semicolon) to also be a valid CSS production. This results in the following contradiction in: h1{--example: {}
is it to be treated as h1{--foo:{;}
or h1{--foo:{}
the later of which is an unterminated block or in the following: h1{--foo:{} h1{color:red;}
should it be h1 {--foo:{}h1{color:red;};
where {}h1{color:red;
is part of the css variable --foo
and not a new rule or should it be something else?
Nevertheless Stylis still supports the exotic forms highlighted in the spec, however you should consider it as a general rule to delimit such exotic uses of variables in strings or parentheses i.e: h1{--foo:'{'}
or h1{--foo:({)}
.
Stylis is at-least 2X faster than its predecesor.
Stylis is MIT licensed.
No vulnerabilities found.
No security vulnerabilities found.